1 /******************************************************************************
5 * Video driver for EasyCAP USB2.0 Video Capture Device DC60 *
8 ******************************************************************************/
11 * Copyright (C) 2010 R.M. Thomas <rmthomas@sciolus.org>
14 * This is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
19 * The software is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this software; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 /*****************************************************************************/
32 #include "easycap_standard.h"
35 module_param(easycap_debug
, int, S_IRUGO
| S_IWUSR
);
37 /*---------------------------------------------------------------------------*/
39 * PARAMETERS APPLICABLE TO ENTIRE DRIVER, I.E. BOTH VIDEO AND AUDIO
41 /*---------------------------------------------------------------------------*/
42 struct usb_device_id easycap_usb_device_id_table
[] = {
43 { USB_DEVICE(USB_EASYCAP_VENDOR_ID
, USB_EASYCAP_PRODUCT_ID
) },
46 MODULE_DEVICE_TABLE(usb
, easycap_usb_device_id_table
);
47 struct usb_driver easycap_usb_driver
= {
49 .id_table
= easycap_usb_device_id_table
,
50 .probe
= easycap_usb_probe
,
51 .disconnect
= easycap_usb_disconnect
,
53 /*---------------------------------------------------------------------------*/
55 * PARAMETERS USED WHEN REGISTERING THE VIDEO INTERFACE
57 * NOTE: SOME KERNELS IGNORE usb_class_driver.minor_base, AS MENTIONED BY
58 * CORBET ET AL. "LINUX DEVICE DRIVERS", 3rd EDITION, PAGE 253.
59 * THIS IS THE CASE FOR OpenSUSE.
61 /*---------------------------------------------------------------------------*/
62 const struct file_operations easycap_fops
= {
65 .release
= easycap_release
,
66 .ioctl
= easycap_ioctl
,
71 struct vm_operations_struct easycap_vm_ops
= {
72 .open
= easycap_vma_open
,
73 .close
= easycap_vma_close
,
74 .fault
= easycap_vma_fault
,
76 struct usb_class_driver easycap_class
= {
77 .name
= "usb/easycap%d",
78 .fops
= &easycap_fops
,
79 .minor_base
= USB_SKEL_MINOR_BASE
,
82 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
83 #if defined(EASYCAP_IS_VIDEODEV_CLIENT)
84 #if defined(EASYCAP_NEEDS_V4L2_FOPS)
85 const struct v4l2_file_operations v4l2_fops
= {
87 .open
= easycap_open_noinode
,
88 .release
= easycap_release_noinode
,
89 .ioctl
= easycap_ioctl_noinode
,
93 #endif /*EASYCAP_NEEDS_V4L2_FOPS*/
94 int video_device_many
/*=0*/;
95 struct video_device
*pvideo_array
[VIDEO_DEVICE_MANY
], *pvideo_device
;
96 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
97 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
99 /*--------------------------------------------------------------------------*/
101 * PARAMETERS USED WHEN REGISTERING THE AUDIO INTERFACE
103 /*--------------------------------------------------------------------------*/
104 const struct file_operations easysnd_fops
= {
105 .owner
= THIS_MODULE
,
106 .open
= easysnd_open
,
107 .release
= easysnd_release
,
108 .ioctl
= easysnd_ioctl
,
109 .read
= easysnd_read
,
112 struct usb_class_driver easysnd_class
= {
113 .name
= "usb/easysnd%d",
114 .fops
= &easysnd_fops
,
115 .minor_base
= USB_SKEL_MINOR_BASE
,
117 /****************************************************************************/
118 /*--------------------------------------------------------------------------*/
120 * IT IS NOT APPROPRIATE FOR easycap_open() TO SUBMIT THE VIDEO URBS HERE,
121 * BECAUSE THERE WILL ALWAYS BE SUBSEQUENT NEGOTIATION OF TV STANDARD AND
122 * FORMAT BY IOCTL AND IT IS INADVISABLE TO HAVE THE URBS RUNNING WHILE
123 * REGISTERS OF THE SA7113H ARE BEING MANIPULATED.
125 * THE SUBMISSION OF VIDEO URBS IS THEREFORE DELAYED UNTIL THE IOCTL COMMAND
126 * STREAMON IS RECEIVED.
128 /*--------------------------------------------------------------------------*/
129 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
130 #if defined(EASYCAP_IS_VIDEODEV_CLIENT)
132 easycap_open_noinode(struct file
*file
)
134 return easycap_open((struct inode
*)NULL
, file
);
136 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
137 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
139 easycap_open(struct inode
*inode
, struct file
*file
)
141 #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
142 struct usb_interface
*pusb_interface
;
143 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
144 struct usb_device
*p
;
145 struct easycap
*peasycap
;
149 SAY("==========OPEN=========\n");
151 peasycap
= (struct easycap
*)NULL
;
152 #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
153 if ((struct inode
*)NULL
== inode
) {
154 SAY("ERROR: inode is NULL.\n");
157 pusb_interface
= usb_find_interface(&easycap_usb_driver
, iminor(inode
));
158 if (!pusb_interface
) {
159 SAY("ERROR: pusb_interface is NULL.\n");
162 peasycap
= usb_get_intfdata(pusb_interface
);
163 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
165 for (i
= 0; i
< video_device_many
; i
++) {
166 pvideo_device
= pvideo_array
[i
];
167 if ((struct video_device
*)NULL
!= pvideo_device
) {
168 peasycap
= (struct easycap
*)video_get_drvdata(pvideo_device
);
172 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
173 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
174 if ((struct easycap
*)NULL
== peasycap
) {
175 SAY("MISTAKE: peasycap is NULL\n");
178 file
->private_data
= peasycap
;
179 /*---------------------------------------------------------------------------*/
183 /*---------------------------------------------------------------------------*/
184 JOT(4, "starting initialization\n");
186 for (k
= 0; k
< FRAME_BUFFER_MANY
; k
++) {
187 for (m
= 0; m
< FRAME_BUFFER_SIZE
/PAGE_SIZE
; m
++)
188 memset(peasycap
->frame_buffer
[k
][m
].pgo
, 0, PAGE_SIZE
);
190 p
= peasycap
->pusb_device
;
191 if ((struct usb_device
*)NULL
== p
) {
192 SAY("ERROR: peasycap->pusb_device is NULL\n");
195 JOT(16, "0x%08lX=peasycap->pusb_device\n", \
196 (long int)peasycap
->pusb_device
);
198 rc
= wakeup_device(peasycap
->pusb_device
);
200 JOT(8, "wakeup_device() OK\n");
202 SAY("ERROR: wakeup_device() returned %i\n", rc
);
205 rc
= setup_stk(p
); peasycap
->input
= 0;
207 JOT(8, "setup_stk() OK\n");
209 SAY("ERROR: setup_stk() returned %i\n", rc
);
214 JOT(8, "setup_saa() OK\n");
216 SAY("ERROR: setup_saa() returned %i\n", rc
);
221 JOT(8, "check_saa() OK\n");
223 SAY("check_saa() returned %i\n", rc
);
225 SAY("ERROR: check_saa() returned %i\n", rc
);
228 peasycap
->standard_offset
= -1;
229 /*---------------------------------------------------------------------------*/
230 #if defined(PREFER_NTSC)
232 rc
= adjust_standard(peasycap
, V4L2_STD_NTSC_M
);
234 JOT(8, "adjust_standard(.,NTSC_M) OK\n");
236 SAY("ERROR: adjust_standard(.,NTSC_M) returned %i\n", rc
);
239 rc
= adjust_format(peasycap
, 640, 480, V4L2_PIX_FMT_UYVY
, V4L2_FIELD_NONE
, \
242 JOT(8, "adjust_format(.,640,480,UYVY) OK\n");
244 SAY("ERROR: adjust_format(.,640,480,UYVY) returned %i\n", rc
);
250 rc
= adjust_standard(peasycap
, \
251 (V4L2_STD_PAL_B
| V4L2_STD_PAL_G
| V4L2_STD_PAL_H
| \
252 V4L2_STD_PAL_I
| V4L2_STD_PAL_N
));
254 JOT(8, "adjust_standard(.,PAL_BGHIN) OK\n");
256 SAY("ERROR: adjust_standard(.,PAL_BGHIN) returned %i\n", rc
);
259 rc
= adjust_format(peasycap
, 640, 480, V4L2_PIX_FMT_UYVY
, V4L2_FIELD_NONE
, \
262 JOT(8, "adjust_format(.,640,480,uyvy,false) OK\n");
264 SAY("ERROR: adjust_format(.,640,480,uyvy,false) returned %i\n", rc
);
268 #endif /* !PREFER_NTSC*/
269 /*---------------------------------------------------------------------------*/
270 rc
= adjust_brightness(peasycap
, -8192);
272 SAY("ERROR: adjust_brightness(default) returned %i\n", rc
);
275 rc
= adjust_contrast(peasycap
, -8192);
277 SAY("ERROR: adjust_contrast(default) returned %i\n", rc
);
280 rc
= adjust_saturation(peasycap
, -8192);
282 SAY("ERROR: adjust_saturation(default) returned %i\n", rc
);
285 rc
= adjust_hue(peasycap
, -8192);
287 SAY("ERROR: adjust_hue(default) returned %i\n", rc
);
290 /*---------------------------------------------------------------------------*/
291 rc
= usb_set_interface(peasycap
->pusb_device
, peasycap
->video_interface
, \
292 peasycap
->video_altsetting_on
);
294 JOT(8, "usb_set_interface(.,%i,%i) OK\n", peasycap
->video_interface
, \
295 peasycap
->video_altsetting_on
);
297 SAY("ERROR: usb_set_interface() returned %i\n", rc
);
302 JOT(8, "start_100() OK\n");
304 SAY("ERROR: start_100() returned %i\n", rc
);
307 peasycap
->video_isoc_sequence
= VIDEO_ISOC_BUFFER_MANY
- 1;
308 peasycap
->video_idle
= 0;
309 peasycap
->video_junk
= 0;
310 for (i
= 0; i
< 180; i
++)
311 peasycap
->merit
[i
] = 0;
312 peasycap
->video_eof
= 0;
313 peasycap
->audio_eof
= 0;
315 do_gettimeofday(&peasycap
->timeval7
);
319 JOT(4, "finished initialization\n");
322 /*****************************************************************************/
324 submit_video_urbs(struct easycap
*peasycap
)
326 struct data_urb
*pdata_urb
;
328 struct list_head
*plist_head
;
332 if ((struct list_head
*)NULL
== peasycap
->purb_video_head
) {
333 SAY("ERROR: peasycap->urb_video_head uninitialized\n");
336 if ((struct usb_device
*)NULL
== peasycap
->pusb_device
) {
337 SAY("ERROR: peasycap->pusb_device is NULL\n");
340 if (!peasycap
->video_isoc_streaming
) {
349 JOT(4, "submission of all video urbs\n");
350 if (0 != ready_saa(peasycap
->pusb_device
)) {
351 SAY("ERROR: not ready to capture after waiting " \
353 SAY("..... continuing anyway\n");
356 list_for_each(plist_head
, (peasycap
->purb_video_head
)) {
357 pdata_urb
= list_entry(plist_head
, struct data_urb
, list_head
);
358 if (NULL
!= pdata_urb
) {
359 purb
= pdata_urb
->purb
;
361 isbuf
= pdata_urb
->isbuf
;
363 purb
->dev
= peasycap
->pusb_device
;
365 usb_rcvisocpipe(peasycap
->pusb_device
,\
366 peasycap
->video_endpointnumber
);
367 purb
->transfer_flags
= URB_ISO_ASAP
;
368 purb
->transfer_buffer
= \
369 peasycap
->video_isoc_buffer
[isbuf
].pgo
;
370 purb
->transfer_buffer_length
= \
371 peasycap
->video_isoc_buffer_size
;
372 purb
->complete
= easycap_complete
;
373 purb
->context
= peasycap
;
374 purb
->start_frame
= 0;
375 purb
->number_of_packets
= \
376 peasycap
->video_isoc_framesperdesc
;
378 for (j
= 0; j
< peasycap
->\
379 video_isoc_framesperdesc
; j
++) {
380 purb
->iso_frame_desc
[j
].\
383 video_isoc_maxframesize
;
384 purb
->iso_frame_desc
[j
].\
386 video_isoc_maxframesize
;
389 rc
= usb_submit_urb(purb
, GFP_KERNEL
);
392 SAY("ERROR: usb_submit_urb() failed " \
393 "for urb with rc:\n");
428 SAY("unknown error code %i\n",\
444 JOT(4, "attempting cleanup instead of submitting\n");
445 list_for_each(plist_head
, (peasycap
->purb_video_head
)) {
446 pdata_urb
= list_entry(plist_head
, struct data_urb
, \
448 if (NULL
!= pdata_urb
) {
449 purb
= pdata_urb
->purb
;
454 peasycap
->video_isoc_streaming
= 0;
456 peasycap
->video_isoc_streaming
= 1;
457 JOT(4, "submitted %i video urbs\n", m
);
466 JOT(4, "already streaming video urbs\n");
470 /*****************************************************************************/
472 kill_video_urbs(struct easycap
*peasycap
)
475 struct list_head
*plist_head
;
476 struct data_urb
*pdata_urb
;
478 if ((struct easycap
*)NULL
== peasycap
) {
479 SAY("ERROR: peasycap is NULL\n");
482 if (peasycap
->video_isoc_streaming
) {
486 if ((struct list_head
*)NULL
!= peasycap
->purb_video_head
) {
487 peasycap
->video_isoc_streaming
= 0;
488 JOT(4, "killing video urbs\n");
490 list_for_each(plist_head
, (peasycap
->purb_video_head
)) {
491 pdata_urb
= list_entry(plist_head
, struct data_urb
, \
493 if ((struct data_urb
*)NULL
!= pdata_urb
) {
494 if ((struct urb
*)NULL
!= pdata_urb
->purb
) {
495 usb_kill_urb(pdata_urb
->purb
);
500 JOT(4, "%i video urbs killed\n", m
);
502 SAY("ERROR: peasycap->purb_video_head is NULL\n");
506 JOT(8, "%i=video_isoc_streaming, no video urbs killed\n", \
507 peasycap
->video_isoc_streaming
);
511 /****************************************************************************/
512 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
513 #if defined(EASYCAP_IS_VIDEODEV_CLIENT)
515 easycap_release_noinode(struct file
*file
)
517 return easycap_release((struct inode
*)NULL
, file
);
519 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
520 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
521 /*--------------------------------------------------------------------------*/
523 easycap_release(struct inode
*inode
, struct file
*file
)
525 #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
526 struct easycap
*peasycap
;
530 peasycap
= file
->private_data
;
531 if (NULL
== peasycap
) {
532 SAY("ERROR: peasycap is NULL.\n");
533 SAY("ending unsuccessfully\n");
536 if (0 != kill_video_urbs(peasycap
)) {
537 SAY("ERROR: kill_video_urbs() failed\n");
540 JOT(4, "ending successfully\n");
541 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
544 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
545 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
549 /****************************************************************************/
550 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
551 #if defined(EASYCAP_IS_VIDEODEV_CLIENT)
553 videodev_release(struct video_device
*pvd
)
555 struct easycap
*peasycap
;
561 for (i
= 0; i
< video_device_many
; i
++) {
562 pvideo_device
= pvideo_array
[i
];
563 if ((struct video_device
*)NULL
!= pvideo_device
) {
564 if (pvd
->minor
== pvideo_device
->minor
) {
565 peasycap
= (struct easycap
*)\
566 video_get_drvdata(pvideo_device
);
567 if ((struct easycap
*)NULL
== peasycap
) {
568 SAY("ERROR: peasycap is NULL\n");
569 SAY("ending unsuccessfully\n");
572 if (0 != kill_video_urbs(peasycap
)) {
573 SAY("ERROR: kill_video_urbs() failed\n");
576 JOT(4, "freeing video_device structure: " \
577 "/dev/video%i\n", i
);
578 kfree((void *)pvideo_device
);
579 for (j
= i
; j
< (VIDEO_DEVICE_MANY
- 1); j
++)
580 pvideo_array
[j
] = pvideo_array
[j
+ 1];
581 video_device_many
--; k
++;
587 SAY("ERROR: lost video_device structure for %i=minor\n", pvd
->minor
);
588 SAY("cannot free: may cause memory leak\n");
589 SAY("ending unsuccessfully\n");
593 JOT(4, "ending successfully\n");
596 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
597 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
598 /****************************************************************************/
599 /*--------------------------------------------------------------------------*/
601 * THIS FUNCTION IS CALLED FROM WITHIN easycap_usb_disconnect().
602 * BY THIS STAGE THE DEVICE HAS ALREADY BEEN PHYSICALLY UNPLUGGED.
603 * peasycap->pusb_device IS NO LONGER VALID AND SHOULD HAVE BEEN SET TO NULL.
605 /*---------------------------------------------------------------------------*/
607 easycap_delete(struct kref
*pkref
)
610 int allocation_video_urb
, allocation_video_page
, allocation_video_struct
;
611 int allocation_audio_urb
, allocation_audio_page
, allocation_audio_struct
;
612 int registered_video
, registered_audio
;
613 struct easycap
*peasycap
;
614 struct data_urb
*pdata_urb
;
615 struct list_head
*plist_head
, *plist_next
;
619 peasycap
= container_of(pkref
, struct easycap
, kref
);
620 if ((struct easycap
*)NULL
== peasycap
) {
621 SAY("ERROR: peasycap is NULL: cannot perform deletions\n");
624 /*---------------------------------------------------------------------------*/
628 /*---------------------------------------------------------------------------*/
629 if ((struct list_head
*)NULL
!= peasycap
->purb_video_head
) {
630 JOT(4, "freeing video urbs\n");
632 list_for_each(plist_head
, (peasycap
->purb_video_head
)) {
633 pdata_urb
= list_entry(plist_head
, struct data_urb
, list_head
);
634 if (NULL
== pdata_urb
)
635 JOT(4, "ERROR: pdata_urb is NULL\n");
637 if ((struct urb
*)NULL
!= pdata_urb
->purb
) {
638 usb_free_urb(pdata_urb
->purb
);
639 pdata_urb
->purb
= (struct urb
*)NULL
;
640 peasycap
->allocation_video_urb
-= 1;
646 JOT(4, "%i video urbs freed\n", m
);
647 /*---------------------------------------------------------------------------*/
648 JOT(4, "freeing video data_urb structures.\n");
650 list_for_each_safe(plist_head
, plist_next
, peasycap
->purb_video_head
) {
651 pdata_urb
= list_entry(plist_head
, struct data_urb
, list_head
);
652 if ((struct data_urb
*)NULL
!= pdata_urb
) {
653 kfree(pdata_urb
); pdata_urb
= (struct data_urb
*)NULL
;
654 peasycap
->allocation_video_struct
-= \
655 sizeof(struct data_urb
);
659 JOT(4, "%i video data_urb structures freed\n", m
);
660 JOT(4, "setting peasycap->purb_video_head=NULL\n");
661 peasycap
->purb_video_head
= (struct list_head
*)NULL
;
663 JOT(4, "peasycap->purb_video_head is NULL\n");
665 /*---------------------------------------------------------------------------*/
666 JOT(4, "freeing video isoc buffers.\n");
668 for (k
= 0; k
< VIDEO_ISOC_BUFFER_MANY
; k
++) {
669 if ((void *)NULL
!= peasycap
->video_isoc_buffer
[k
].pgo
) {
670 free_pages((unsigned long)\
671 (peasycap
->video_isoc_buffer
[k
].pgo
), \
673 peasycap
->video_isoc_buffer
[k
].pgo
= (void *)NULL
;
674 peasycap
->allocation_video_page
-= \
675 ((unsigned int)(0x01 << VIDEO_ISOC_ORDER
));
679 JOT(4, "isoc video buffers freed: %i pages\n", m
* (0x01 << VIDEO_ISOC_ORDER
));
680 /*---------------------------------------------------------------------------*/
681 JOT(4, "freeing video field buffers.\n");
683 for (k
= 0; k
< FIELD_BUFFER_MANY
; k
++) {
684 for (m
= 0; m
< FIELD_BUFFER_SIZE
/PAGE_SIZE
; m
++) {
685 if ((void *)NULL
!= peasycap
->field_buffer
[k
][m
].pgo
) {
686 free_page((unsigned long)\
687 (peasycap
->field_buffer
[k
][m
].pgo
));
688 peasycap
->field_buffer
[k
][m
].pgo
= (void *)NULL
;
689 peasycap
->allocation_video_page
-= 1;
694 JOT(4, "video field buffers freed: %i pages\n", lost
);
695 /*---------------------------------------------------------------------------*/
696 JOT(4, "freeing video frame buffers.\n");
698 for (k
= 0; k
< FRAME_BUFFER_MANY
; k
++) {
699 for (m
= 0; m
< FRAME_BUFFER_SIZE
/PAGE_SIZE
; m
++) {
700 if ((void *)NULL
!= peasycap
->frame_buffer
[k
][m
].pgo
) {
701 free_page((unsigned long)\
702 (peasycap
->frame_buffer
[k
][m
].pgo
));
703 peasycap
->frame_buffer
[k
][m
].pgo
= (void *)NULL
;
704 peasycap
->allocation_video_page
-= 1;
709 JOT(4, "video frame buffers freed: %i pages\n", lost
);
710 /*---------------------------------------------------------------------------*/
714 /*---------------------------------------------------------------------------*/
715 if ((struct list_head
*)NULL
!= peasycap
->purb_audio_head
) {
716 JOT(4, "freeing audio urbs\n");
718 list_for_each(plist_head
, (peasycap
->purb_audio_head
)) {
719 pdata_urb
= list_entry(plist_head
, struct data_urb
, list_head
);
720 if (NULL
== pdata_urb
)
721 JOT(4, "ERROR: pdata_urb is NULL\n");
723 if ((struct urb
*)NULL
!= pdata_urb
->purb
) {
724 usb_free_urb(pdata_urb
->purb
);
725 pdata_urb
->purb
= (struct urb
*)NULL
;
726 peasycap
->allocation_audio_urb
-= 1;
731 JOT(4, "%i audio urbs freed\n", m
);
732 /*---------------------------------------------------------------------------*/
733 JOT(4, "freeing audio data_urb structures.\n");
735 list_for_each_safe(plist_head
, plist_next
, peasycap
->purb_audio_head
) {
736 pdata_urb
= list_entry(plist_head
, struct data_urb
, list_head
);
737 if ((struct data_urb
*)NULL
!= pdata_urb
) {
738 kfree(pdata_urb
); pdata_urb
= (struct data_urb
*)NULL
;
739 peasycap
->allocation_audio_struct
-= \
740 sizeof(struct data_urb
);
744 JOT(4, "%i audio data_urb structures freed\n", m
);
745 JOT(4, "setting peasycap->purb_audio_head=NULL\n");
746 peasycap
->purb_audio_head
= (struct list_head
*)NULL
;
748 JOT(4, "peasycap->purb_audio_head is NULL\n");
750 /*---------------------------------------------------------------------------*/
751 JOT(4, "freeing audio isoc buffers.\n");
753 for (k
= 0; k
< AUDIO_ISOC_BUFFER_MANY
; k
++) {
754 if ((void *)NULL
!= peasycap
->audio_isoc_buffer
[k
].pgo
) {
755 free_pages((unsigned long)\
756 (peasycap
->audio_isoc_buffer
[k
].pgo
), \
758 peasycap
->audio_isoc_buffer
[k
].pgo
= (void *)NULL
;
759 peasycap
->allocation_audio_page
-= \
760 ((unsigned int)(0x01 << AUDIO_ISOC_ORDER
));
764 JOT(4, "easysnd_delete(): isoc audio buffers freed: %i pages\n", \
765 m
* (0x01 << AUDIO_ISOC_ORDER
));
766 /*---------------------------------------------------------------------------*/
767 JOT(4, "freeing audio buffers.\n");
769 for (k
= 0; k
< peasycap
->audio_buffer_page_many
; k
++) {
770 if ((void *)NULL
!= peasycap
->audio_buffer
[k
].pgo
) {
771 free_page((unsigned long)(peasycap
->audio_buffer
[k
].pgo
));
772 peasycap
->audio_buffer
[k
].pgo
= (void *)NULL
;
773 peasycap
->allocation_audio_page
-= 1;
777 JOT(4, "easysnd_delete(): audio buffers freed: %i pages\n", lost
);
778 /*---------------------------------------------------------------------------*/
779 JOT(4, "freeing easycap structure.\n");
780 allocation_video_urb
= peasycap
->allocation_video_urb
;
781 allocation_video_page
= peasycap
->allocation_video_page
;
782 allocation_video_struct
= peasycap
->allocation_video_struct
;
783 registered_video
= peasycap
->registered_video
;
784 allocation_audio_urb
= peasycap
->allocation_audio_urb
;
785 allocation_audio_page
= peasycap
->allocation_audio_page
;
786 allocation_audio_struct
= peasycap
->allocation_audio_struct
;
787 registered_audio
= peasycap
->registered_audio
;
789 if ((struct easycap
*)NULL
!= peasycap
) {
790 kfree(peasycap
); peasycap
= (struct easycap
*)NULL
;
791 allocation_video_struct
-= sizeof(struct easycap
);
794 JOT(4, "%i easycap structure freed\n", m
);
795 /*---------------------------------------------------------------------------*/
797 SAY("%8i= video urbs after all deletions\n", allocation_video_urb
);
798 SAY("%8i= video pages after all deletions\n", allocation_video_page
);
799 SAY("%8i= video structs after all deletions\n", allocation_video_struct
);
800 SAY("%8i= video devices after all deletions\n", registered_video
);
801 SAY("%8i= audio urbs after all deletions\n", allocation_audio_urb
);
802 SAY("%8i= audio pages after all deletions\n", allocation_audio_page
);
803 SAY("%8i= audio structs after all deletions\n", allocation_audio_struct
);
804 SAY("%8i= audio devices after all deletions\n", registered_audio
);
809 /*****************************************************************************/
810 unsigned int easycap_poll(struct file
*file
, poll_table
*wait
)
812 struct easycap
*peasycap
;
816 if (NULL
== ((poll_table
*)wait
))
817 JOT(8, "WARNING: poll table pointer is NULL ... continuing\n");
818 if (NULL
== ((struct file
*)file
)) {
819 SAY("ERROR: file pointer is NULL\n");
822 peasycap
= file
->private_data
;
823 if (NULL
== peasycap
) {
824 SAY("ERROR: peasycap is NULL\n");
827 peasycap
->polled
= 1;
829 if (0 == easycap_dqbuf(peasycap
, 0))
830 return POLLIN
| POLLRDNORM
;
835 /*****************************************************************************/
836 /*---------------------------------------------------------------------------*/
838 * IF mode IS NONZERO THIS ROUTINE RETURNS -EAGAIN RATHER THAN BLOCKING.
840 /*---------------------------------------------------------------------------*/
842 easycap_dqbuf(struct easycap
*peasycap
, int mode
)
848 if (NULL
== peasycap
) {
849 SAY("ERROR: peasycap is NULL\n");
852 /*---------------------------------------------------------------------------*/
856 /*---------------------------------------------------------------------------*/
858 if (mutex_lock_interruptible(&(peasycap
->mutex_mmap_video
[0])))
860 while ((peasycap
->field_read
== peasycap
->field_fill
) || \
861 (0 != (0xFF00 & peasycap
->field_buffer\
862 [peasycap
->field_read
][0].kount
)) || \
863 (0 != (0x00FF & peasycap
->field_buffer\
864 [peasycap
->field_read
][0].kount
))) {
865 mutex_unlock(&(peasycap
->mutex_mmap_video
[0]));
870 JOT(8, "first wait on wq_video, " \
871 "%i=field_read %i=field_fill\n", \
872 peasycap
->field_read
, peasycap
->field_fill
);
875 if (0 != (wait_event_interruptible(peasycap
->wq_video
, \
876 (peasycap
->video_idle
|| peasycap
->video_eof
|| \
877 ((peasycap
->field_read
!= peasycap
->field_fill
) && \
878 (0 == (0xFF00 & peasycap
->field_buffer\
879 [peasycap
->field_read
][0].kount
)) && \
880 (0 == (0x00FF & peasycap
->field_buffer\
881 [peasycap
->field_read
][0].kount
))))))){
882 SAY("aborted by signal\n");
885 if (peasycap
->video_idle
) {
886 JOT(8, "%i=peasycap->video_idle\n", peasycap
->video_idle
);
889 if (peasycap
->video_eof
) {
890 JOT(8, "%i=peasycap->video_eof\n", peasycap
->video_eof
);
892 kill_video_urbs(peasycap
);
896 if (mutex_lock_interruptible(&(peasycap
->mutex_mmap_video
[0])))
899 mutex_unlock(&(peasycap
->mutex_mmap_video
[0]));
900 JOT(8, "first awakening on wq_video after %i waits\n", miss
);
902 rc
= field2frame(peasycap
);
904 SAY("ERROR: field2frame() returned %i\n", rc
);
906 if (true == peasycap
->offerfields
) {
907 peasycap
->frame_read
= peasycap
->frame_fill
;
908 (peasycap
->frame_fill
)++;
909 if (peasycap
->frame_buffer_many
<= peasycap
->frame_fill
)
910 peasycap
->frame_fill
= 0;
912 if (0x01 & easycap_standard
[peasycap
->standard_offset
].mask
) {
913 peasycap
->frame_buffer
[peasycap
->frame_read
][0].kount
= \
916 peasycap
->frame_buffer
[peasycap
->frame_read
][0].kount
= \
919 JOT(8, "setting: %i=peasycap->frame_read\n", peasycap
->frame_read
);
920 JOT(8, "bumped to: %i=peasycap->frame_fill\n", peasycap
->frame_fill
);
922 /*---------------------------------------------------------------------------*/
926 /*---------------------------------------------------------------------------*/
928 if (mutex_lock_interruptible(&(peasycap
->mutex_mmap_video
[0])))
930 while ((peasycap
->field_read
== peasycap
->field_fill
) || \
931 (0 != (0xFF00 & peasycap
->field_buffer\
932 [peasycap
->field_read
][0].kount
)) || \
933 (0 == (0x00FF & peasycap
->field_buffer\
934 [peasycap
->field_read
][0].kount
))) {
935 mutex_unlock(&(peasycap
->mutex_mmap_video
[0]));
940 JOT(8, "second wait on wq_video, " \
941 "%i=field_read %i=field_fill\n", \
942 peasycap
->field_read
, peasycap
->field_fill
);
944 if (0 != (wait_event_interruptible(peasycap
->wq_video
, \
945 (peasycap
->video_idle
|| peasycap
->video_eof
|| \
946 ((peasycap
->field_read
!= peasycap
->field_fill
) && \
947 (0 == (0xFF00 & peasycap
->field_buffer\
948 [peasycap
->field_read
][0].kount
)) && \
949 (0 != (0x00FF & peasycap
->field_buffer\
950 [peasycap
->field_read
][0].kount
))))))){
951 SAY("aborted by signal\n");
954 if (peasycap
->video_idle
) {
955 JOT(8, "%i=peasycap->video_idle\n", peasycap
->video_idle
);
958 if (peasycap
->video_eof
) {
959 JOT(8, "%i=peasycap->video_eof\n", peasycap
->video_eof
);
961 kill_video_urbs(peasycap
);
965 if (mutex_lock_interruptible(&(peasycap
->mutex_mmap_video
[0])))
968 mutex_unlock(&(peasycap
->mutex_mmap_video
[0]));
969 JOT(8, "second awakening on wq_video after %i waits\n", miss
);
971 rc
= field2frame(peasycap
);
973 SAY("ERROR: field2frame() returned %i\n", rc
);
975 peasycap
->frame_read
= peasycap
->frame_fill
;
976 peasycap
->queued
[peasycap
->frame_read
] = 0;
977 peasycap
->done
[peasycap
->frame_read
] = V4L2_BUF_FLAG_DONE
;
979 (peasycap
->frame_fill
)++;
980 if (peasycap
->frame_buffer_many
<= peasycap
->frame_fill
)
981 peasycap
->frame_fill
= 0;
983 if (0x01 & easycap_standard
[peasycap
->standard_offset
].mask
) {
984 peasycap
->frame_buffer
[peasycap
->frame_read
][0].kount
= \
987 peasycap
->frame_buffer
[peasycap
->frame_read
][0].kount
= \
991 JOT(8, "setting: %i=peasycap->frame_read\n", peasycap
->frame_read
);
992 JOT(8, "bumped to: %i=peasycap->frame_fill\n", peasycap
->frame_fill
);
996 /*****************************************************************************/
997 /*---------------------------------------------------------------------------*/
999 * BY DEFINITION, odd IS true FOR THE FIELD OCCUPYING LINES 1,3,5,...,479
1000 * odd IS false FOR THE FIELD OCCUPYING LINES 0,2,4,...,478
1002 * WHEN BOOLEAN PARAMETER decimatepixel IS true, ONLY THE FIELD FOR WHICH
1003 * odd==false IS TRANSFERRED TO THE FRAME BUFFER.
1005 * THE BOOLEAN PARAMETER offerfields IS true ONLY WHEN THE USER PROGRAM
1006 * CHOOSES THE OPTION V4L2_FIELD_ALTERNATE. NO USERSPACE PROGRAM TESTED
1007 * TO DATE HAS DONE THIS. BUGS ARE LIKELY.
1009 /*---------------------------------------------------------------------------*/
1011 field2frame(struct easycap
*peasycap
)
1013 static struct timeval timeval0
;
1014 struct timeval timeval
;
1015 long long int above
, below
;
1017 struct signed_div_result sdr
;
1020 int kex
, kad
, mex
, mad
, rex
, rad
, rad2
;
1021 int c2
, c3
, w2
, w3
, cz
, wz
;
1022 int rc
, bytesperpixel
, multiplier
, much
, more
, over
, rump
, caches
;
1024 bool odd
, isuy
, decimatepixel
, offerfields
;
1026 JOT(8, "===== parity %i, field buffer %i --> frame buffer %i\n", \
1027 peasycap
->field_buffer
[peasycap
->field_read
][0].kount
,\
1028 peasycap
->field_read
, peasycap
->frame_fill
);
1029 JOT(8, "===== %i=bytesperpixel\n", peasycap
->bytesperpixel
);
1030 if (true == peasycap
->offerfields
)
1031 JOT(8, "===== offerfields\n");
1033 /*---------------------------------------------------------------------------*/
1035 * REJECT OR CLEAN BAD FIELDS
1037 /*---------------------------------------------------------------------------*/
1038 if (peasycap
->field_read
== peasycap
->field_fill
) {
1039 SAY("ERROR: on entry, still filling field buffer %i\n", \
1040 peasycap
->field_read
);
1043 #if defined(EASYCAP_TESTCARD)
1044 easycap_testcard(peasycap
, peasycap
->field_read
);
1046 if (0 != (0x0400 & peasycap
->field_buffer
[peasycap
->field_read
][0].kount
))
1047 easycap_testcard(peasycap
, peasycap
->field_read
);
1048 #endif /*EASYCAP_TESTCARD*/
1049 /*---------------------------------------------------------------------------*/
1051 offerfields
= peasycap
->offerfields
;
1052 bytesperpixel
= peasycap
->bytesperpixel
;
1053 decimatepixel
= peasycap
->decimatepixel
;
1055 if ((2 != bytesperpixel
) && \
1056 (3 != bytesperpixel
) && \
1057 (4 != bytesperpixel
)) {
1058 SAY("MISTAKE: %i=bytesperpixel\n", bytesperpixel
);
1061 if (true == decimatepixel
)
1066 w2
= 2 * multiplier
* (peasycap
->width
);
1067 w3
= bytesperpixel
* \
1071 (peasycap
->height
) * \
1075 kex
= peasycap
->field_read
; mex
= 0;
1076 kad
= peasycap
->frame_fill
; mad
= 0;
1078 pex
= peasycap
->field_buffer
[kex
][0].pgo
; rex
= PAGE_SIZE
;
1079 pad
= peasycap
->frame_buffer
[kad
][0].pgo
; rad
= PAGE_SIZE
;
1080 if (peasycap
->field_buffer
[kex
][0].kount
)
1085 if ((true == odd
) && (false == offerfields
) &&(false == decimatepixel
)) {
1086 JOT(8, " initial skipping %4i bytes p.%4i\n", \
1087 w3
/multiplier
, mad
);
1088 pad
+= (w3
/ multiplier
); rad
-= (w3
/ multiplier
);
1091 mask
= 0; rump
= 0; caches
= 0;
1095 /*-------------------------------------------------------------------*/
1097 ** PROCESS ONE LINE OF FRAME AT FULL RESOLUTION:
1098 ** READ w2 BYTES FROM FIELD BUFFER,
1099 ** WRITE w3 BYTES TO FRAME BUFFER
1101 /*-------------------------------------------------------------------*/
1102 if (false == decimatepixel
) {
1105 much
= over
; more
= 0; margin
= 0; mask
= 0x00;
1111 SAY("MISTAKE: much is odd\n");
1115 more
= (bytesperpixel
* \
1117 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1118 if (1 < bytesperpixel
) {
1123 ** INJUDICIOUS ALTERATION OF THIS
1124 ** BLOCK WILL CAUSE BREAKAGE.
1127 rad2
= rad
+ bytesperpixel
- 1;
1129 rad2
)/bytesperpixel
)/2) * 2);
1130 rump
= ((bytesperpixel
* \
1138 if ((mex
+ 1) < FIELD_BUFFER_SIZE
/ \
1140 margin
= *((__u8
*)(peasycap
->\
1142 [kex
][mex
+ 1].pgo
));
1146 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1148 SAY("MISTAKE: %i=bytesperpixel\n", \
1152 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1156 rc
= redaub(peasycap
, pad
, pex
, much
, more
, \
1157 mask
, margin
, isuy
);
1159 SAY("ERROR: redaub() failed\n");
1168 over
-= much
; cz
+= much
;
1169 pex
+= much
; rex
-= much
;
1172 pex
= peasycap
->field_buffer
[kex
][mex
].pgo
;
1179 pad
= peasycap
->frame_buffer
[kad
][mad
].pgo
;
1187 /*---------------------------------------------------------------------------*/
1189 * SKIP w3 BYTES IN TARGET FRAME BUFFER,
1190 * UNLESS IT IS THE LAST LINE OF AN ODD FRAME
1192 /*---------------------------------------------------------------------------*/
1193 if (((false == odd
) || (cz
!= wz
))&&(false == offerfields
)) {
1198 pad
= peasycap
->frame_buffer\
1210 /*---------------------------------------------------------------------------*/
1212 * PROCESS ONE LINE OF FRAME AT REDUCED RESOLUTION:
1213 * ONLY IF false==odd,
1214 * READ w2 BYTES FROM FIELD BUFFER,
1215 * WRITE w3 / 2 BYTES TO FRAME BUFFER
1217 /*---------------------------------------------------------------------------*/
1218 } else if (false == odd
) {
1221 much
= over
; more
= 0; margin
= 0; mask
= 0x00;
1227 SAY("MISTAKE: much is odd\n");
1231 more
= (bytesperpixel
* \
1233 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1234 if (1 < bytesperpixel
) {
1235 if ((rad
* 4) < (much
* \
1238 ** INJUDICIOUS ALTERATION OF THIS
1239 ** BLOCK WILL CAUSE BREAKAGE.
1242 rad2
= rad
+ bytesperpixel
- 1;
1243 much
= ((((2 * rad2
)/bytesperpixel
)/2)\
1245 rump
= ((bytesperpixel
* \
1253 if ((mex
+ 1) < FIELD_BUFFER_SIZE
/ \
1255 margin
= *((__u8
*)(peasycap
->\
1257 [kex
][mex
+ 1].pgo
));
1262 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1264 SAY("MISTAKE: %i=bytesperpixel\n", \
1268 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1272 rc
= redaub(peasycap
, pad
, pex
, much
, more
, \
1273 mask
, margin
, isuy
);
1275 SAY("ERROR: redaub() failed\n");
1278 over
-= much
; cz
+= much
;
1279 pex
+= much
; rex
-= much
;
1282 pex
= peasycap
->field_buffer
[kex
][mex
].pgo
;
1289 pad
= peasycap
->frame_buffer
[kad
][mad
].pgo
;
1297 /*---------------------------------------------------------------------------*/
1300 * READ w2 BYTES FROM FIELD BUFFER AND DISCARD THEM
1302 /*---------------------------------------------------------------------------*/
1308 pex
= peasycap
->field_buffer
[kex
][mex
].pgo
;
1321 /*---------------------------------------------------------------------------*/
1325 /*---------------------------------------------------------------------------*/
1326 c2
= (mex
+ 1)*PAGE_SIZE
- rex
;
1328 SAY("ERROR: discrepancy %i in bytes read\n", c2
- cz
);
1329 c3
= (mad
+ 1)*PAGE_SIZE
- rad
;
1331 if (false == decimatepixel
) {
1332 if (bytesperpixel
* \
1334 SAY("ERROR: discrepancy %i in bytes written\n", \
1335 c3
- (bytesperpixel
* \
1339 if (bytesperpixel
* \
1341 SAY("ERROR: discrepancy %i in bytes written\n", \
1342 (2*c3
)-(bytesperpixel
* \
1346 SAY("ERROR: discrepancy %i " \
1347 "in bytes written\n", c3
);
1351 SAY("ERROR: undischarged cache at end of line in frame buffer\n");
1353 JOT(8, "===== field2frame(): %i bytes --> %i bytes (incl skip)\n", c2
, c3
);
1354 JOT(8, "===== field2frame(): %i=mad %i=rad\n", mad
, rad
);
1357 JOT(8, "+++++ field2frame(): frame buffer %i is full\n", kad
);
1359 if (peasycap
->field_read
== peasycap
->field_fill
)
1360 SAY("WARNING: on exit, filling field buffer %i\n", \
1361 peasycap
->field_read
);
1362 /*---------------------------------------------------------------------------*/
1364 * CALCULATE VIDEO STREAMING RATE
1366 /*---------------------------------------------------------------------------*/
1367 do_gettimeofday(&timeval
);
1368 if (timeval0
.tv_sec
) {
1369 below
= ((long long int)(1000000)) * \
1370 ((long long int)(timeval
.tv_sec
- timeval0
.tv_sec
)) + \
1371 (long long int)(timeval
.tv_usec
- timeval0
.tv_usec
);
1372 above
= (long long int)1000000;
1374 sdr
= signed_div(above
, below
);
1375 above
= sdr
.quotient
;
1376 remainder
= (__u32
)sdr
.remainder
;
1378 JOT(8, "video streaming at %3lli.%03i fields per second\n", above
, \
1384 JOT(8, "%i=caches\n", caches
);
1387 /*****************************************************************************/
1388 struct signed_div_result
1389 signed_div(long long int above
, long long int below
)
1391 struct signed_div_result sdr
;
1393 if (((0 <= above
) && (0 <= below
)) || ((0 > above
) && (0 > below
))) {
1394 sdr
.remainder
= (unsigned long long int) do_div(above
, below
);
1395 sdr
.quotient
= (long long int) above
;
1401 sdr
.remainder
= (unsigned long long int) do_div(above
, below
);
1402 sdr
.quotient
= -((long long int) above
);
1406 /*****************************************************************************/
1407 /*---------------------------------------------------------------------------*/
1409 * DECIMATION AND COLOURSPACE CONVERSION.
1411 * THIS ROUTINE REQUIRES THAT ALL THE DATA TO BE READ RESIDES ON ONE PAGE
1412 * AND THAT ALL THE DATA TO BE WRITTEN RESIDES ON ONE (DIFFERENT) PAGE.
1413 * THE CALLING ROUTINE MUST ENSURE THAT THIS REQUIREMENT IS MET, AND MUST
1414 * ALSO ENSURE THAT much IS EVEN.
1416 * much BYTES ARE READ, AT LEAST (bytesperpixel * much)/2 BYTES ARE WRITTEN
1417 * IF THERE IS NO DECIMATION, HALF THIS AMOUNT IF THERE IS DECIMATION.
1419 * mask IS ZERO WHEN NO SPECIAL BEHAVIOUR REQUIRED. OTHERWISE IT IS SET THUS:
1420 * 0x03 & mask = number of bytes to be written to cache instead of to
1422 * 0x04 & mask => use argument margin to set the chrominance for last pixel
1423 * 0x08 & mask => do not set the chrominance for last pixel
1425 * YUV to RGB CONVERSION IS (OR SHOULD BE) ITU-R BT 601.
1427 * THERE IS A LOT OF CODE REPETITION IN THIS ROUTINE IN ORDER TO AVOID
1428 * INEFFICIENT SWITCHING INSIDE INNER LOOPS. REARRANGING THE LOGIC TO
1429 * REDUCE CODE LENGTH WILL GENERALLY IMPAIR RUNTIME PERFORMANCE. BEWARE.
1431 /*---------------------------------------------------------------------------*/
1433 redaub(struct easycap
*peasycap
, void *pad
, void *pex
, int much
, int more
, \
1434 __u8 mask
, __u8 margin
, bool isuy
)
1436 static __s32 ay
[256], bu
[256], rv
[256], gu
[256], gv
[256];
1437 static __u8 cache
[8], *pcache
;
1438 __u8 r
, g
, b
, y
, u
, v
, c
, *p2
, *p3
, *pz
, *pr
;
1440 bool byteswaporder
, decimatepixel
, last
;
1445 SAY("MISTAKE: much is odd\n");
1448 bytesperpixel
= peasycap
->bytesperpixel
;
1449 byteswaporder
= peasycap
->byteswaporder
;
1450 decimatepixel
= peasycap
->decimatepixel
;
1452 /*---------------------------------------------------------------------------*/
1454 for (j
= 0; j
< 112; j
++) {
1455 s32
= (0xFF00 & (453 * j
)) >> 8;
1456 bu
[j
+ 128] = s32
; bu
[127 - j
] = -s32
;
1457 s32
= (0xFF00 & (359 * j
)) >> 8;
1458 rv
[j
+ 128] = s32
; rv
[127 - j
] = -s32
;
1459 s32
= (0xFF00 & (88 * j
)) >> 8;
1460 gu
[j
+ 128] = s32
; gu
[127 - j
] = -s32
;
1461 s32
= (0xFF00 & (183 * j
)) >> 8;
1462 gv
[j
+ 128] = s32
; gv
[127 - j
] = -s32
;
1464 for (j
= 0; j
< 16; j
++) {
1465 bu
[j
] = bu
[16]; rv
[j
] = rv
[16];
1466 gu
[j
] = gu
[16]; gv
[j
] = gv
[16];
1468 for (j
= 240; j
< 256; j
++) {
1469 bu
[j
] = bu
[239]; rv
[j
] = rv
[239];
1470 gu
[j
] = gu
[239]; gv
[j
] = gv
[239];
1472 for (j
= 16; j
< 236; j
++)
1474 for (j
= 0; j
< 16; j
++)
1476 for (j
= 236; j
< 256; j
++)
1478 JOT(8, "lookup tables are prepared\n");
1480 if ((__u8
*)NULL
== pcache
)
1482 /*---------------------------------------------------------------------------*/
1484 * TRANSFER CONTENTS OF CACHE TO THE FRAME BUFFER
1486 /*---------------------------------------------------------------------------*/
1488 SAY("MISTAKE: pcache is NULL\n");
1492 if (pcache
!= &cache
[0])
1493 JOT(16, "cache has %i bytes\n", (int)(pcache
- &cache
[0]));
1495 p3
= (__u8
*)pad
- (int)(pcache
- &cache
[0]);
1496 while (p2
< pcache
) {
1501 SAY("MISTAKE: pointer misalignment\n");
1504 /*---------------------------------------------------------------------------*/
1505 rump
= (int)(0x03 & mask
);
1507 p2
= (__u8
*)pex
; pz
= p2
+ much
; pr
= p3
+ more
; last
= false;
1516 JOT(16, "%4i=much %4i=more %i=rump\n", much
, more
, rump
);
1518 /*---------------------------------------------------------------------------*/
1519 switch (bytesperpixel
) {
1521 if (false == decimatepixel
) {
1522 memcpy(pad
, pex
, (size_t)much
);
1523 if (false == byteswaporder
)
1524 /*---------------------------------------------------*/
1528 /*---------------------------------------------------*/
1531 /*---------------------------------------------------*/
1535 /*---------------------------------------------------*/
1536 p3
= (__u8
*)pad
; pz
= p3
+ much
;
1546 if (false == byteswaporder
) {
1547 /*---------------------------------------------------*/
1551 /*---------------------------------------------------*/
1552 p2
= (__u8
*)pex
; p3
= (__u8
*)pad
; pz
= p2
+ much
;
1555 *(p3
+ 1) = *(p2
+ 1);
1556 *(p3
+ 2) = *(p2
+ 2);
1557 *(p3
+ 3) = *(p2
+ 3);
1562 /*---------------------------------------------------*/
1566 /*---------------------------------------------------*/
1567 p2
= (__u8
*)pex
; p3
= (__u8
*)pad
; pz
= p2
+ much
;
1571 *(p3
+ 2) = *(p2
+ 3);
1572 *(p3
+ 3) = *(p2
+ 2);
1582 if (false == decimatepixel
) {
1583 if (false == byteswaporder
) {
1584 /*---------------------------------------------------*/
1588 /*---------------------------------------------------*/
1590 if (pr
<= (p3
+ bytesperpixel
))
1595 if ((true == last
) && (0x0C & mask
)) {
1611 s32
= ay
[(int)y
] + rv
[(int)v
];
1612 r
= (255 < s32
) ? 255 : ((0 > s32
) ? \
1614 s32
= ay
[(int)y
] - gu
[(int)u
] - gv
[(int)v
];
1615 g
= (255 < s32
) ? 255 : ((0 > s32
) ? \
1617 s32
= ay
[(int)y
] + bu
[(int)u
];
1618 b
= (255 < s32
) ? 255 : ((0 > s32
) ? \
1621 if ((true == last
) && rump
) {
1623 switch (bytesperpixel
- rump
) {
1637 SAY("MISTAKE: %i=rump\n", \
1638 bytesperpixel
- rump
);
1652 p3
+= bytesperpixel
;
1656 /*---------------------------------------------------*/
1660 /*---------------------------------------------------*/
1662 if (pr
<= (p3
+ bytesperpixel
))
1667 if ((true == last
) && (0x0C & mask
)) {
1684 s32
= ay
[(int)y
] + rv
[(int)v
];
1685 r
= (255 < s32
) ? 255 : ((0 > s32
) ? \
1687 s32
= ay
[(int)y
] - gu
[(int)u
] - gv
[(int)v
];
1688 g
= (255 < s32
) ? 255 : ((0 > s32
) ? \
1690 s32
= ay
[(int)y
] + bu
[(int)u
];
1691 b
= (255 < s32
) ? 255 : ((0 > s32
) ? \
1694 if ((true == last
) && rump
) {
1696 switch (bytesperpixel
- rump
) {
1710 SAY("MISTAKE: %i=rump\n", \
1711 bytesperpixel
- rump
);
1725 p3
+= bytesperpixel
;
1730 if (false == byteswaporder
) {
1731 /*---------------------------------------------------*/
1735 /*---------------------------------------------------*/
1737 if (pr
<= (p3
+ bytesperpixel
))
1742 if ((true == last
) && (0x0C & mask
)) {
1759 s32
= ay
[(int)y
] + rv
[(int)v
];
1760 r
= (255 < s32
) ? 255 : ((0 > s32
) ? \
1762 s32
= ay
[(int)y
] - gu
[(int)u
] - \
1764 g
= (255 < s32
) ? 255 : ((0 > s32
) ? \
1766 s32
= ay
[(int)y
] + bu
[(int)u
];
1767 b
= (255 < s32
) ? 255 : ((0 > s32
) ? \
1770 if ((true == last
) && rump
) {
1772 switch (bytesperpixel
- rump
) {
1788 bytesperpixel
- rump
);
1798 p3
+= bytesperpixel
;
1806 /*---------------------------------------------------*/
1810 /*---------------------------------------------------*/
1812 if (pr
<= (p3
+ bytesperpixel
))
1817 if ((true == last
) && (0x0C & mask
)) {
1835 s32
= ay
[(int)y
] + rv
[(int)v
];
1836 r
= (255 < s32
) ? 255 : ((0 > s32
) ? \
1838 s32
= ay
[(int)y
] - gu
[(int)u
] - \
1840 g
= (255 < s32
) ? 255 : ((0 > s32
) ? \
1842 s32
= ay
[(int)y
] + bu
[(int)u
];
1843 b
= (255 < s32
) ? 255 : ((0 > s32
) ? \
1846 if ((true == last
) && rump
) {
1848 switch (bytesperpixel
- rump
) {
1864 bytesperpixel
- rump
);
1874 p3
+= bytesperpixel
;
1887 if (false == decimatepixel
) {
1888 if (false == byteswaporder
) {
1889 /*---------------------------------------------------*/
1893 /*---------------------------------------------------*/
1895 if (pr
<= (p3
+ bytesperpixel
))
1900 if ((true == last
) && (0x0C & mask
)) {
1916 s32
= ay
[(int)y
] + rv
[(int)v
];
1917 r
= (255 < s32
) ? 255 : ((0 > s32
) ? \
1919 s32
= ay
[(int)y
] - gu
[(int)u
] - gv
[(int)v
];
1920 g
= (255 < s32
) ? 255 : ((0 > s32
) ? \
1922 s32
= ay
[(int)y
] + bu
[(int)u
];
1923 b
= (255 < s32
) ? 255 : ((0 > s32
) ? \
1926 if ((true == last
) && rump
) {
1928 switch (bytesperpixel
- rump
) {
1951 SAY("MISTAKE: %i=rump\n", \
1952 bytesperpixel
- rump
);
1967 p3
+= bytesperpixel
;
1971 /*---------------------------------------------------*/
1975 /*---------------------------------------------------*/
1977 if (pr
<= (p3
+ bytesperpixel
))
1982 if ((true == last
) && (0x0C & mask
)) {
1998 s32
= ay
[(int)y
] + rv
[(int)v
];
1999 r
= (255 < s32
) ? 255 : ((0 > s32
) ? \
2001 s32
= ay
[(int)y
] - gu
[(int)u
] - gv
[(int)v
];
2002 g
= (255 < s32
) ? 255 : ((0 > s32
) ? \
2004 s32
= ay
[(int)y
] + bu
[(int)u
];
2005 b
= (255 < s32
) ? 255 : ((0 > s32
) ? \
2008 if ((true == last
) && rump
) {
2010 switch (bytesperpixel
- rump
) {
2033 SAY("MISTAKE: %i=rump\n", \
2034 bytesperpixel
- rump
);
2049 p3
+= bytesperpixel
;
2054 if (false == byteswaporder
) {
2055 /*---------------------------------------------------*/
2059 /*---------------------------------------------------*/
2061 if (pr
<= (p3
+ bytesperpixel
))
2066 if ((true == last
) && (0x0C & mask
)) {
2084 s32
= ay
[(int)y
] + rv
[(int)v
];
2085 r
= (255 < s32
) ? 255 : ((0 > s32
) ? \
2087 s32
= ay
[(int)y
] - gu
[(int)u
] - \
2089 g
= (255 < s32
) ? 255 : ((0 > s32
) ? \
2091 s32
= ay
[(int)y
] + bu
[(int)u
];
2092 b
= (255 < s32
) ? 255 : ((0 > s32
) ? \
2095 if ((true == last
) && rump
) {
2097 switch (bytesperpixel
- rump
) {
2134 p3
+= bytesperpixel
;
2141 /*---------------------------------------------------*/
2145 /*---------------------------------------------------*/
2147 if (pr
<= (p3
+ bytesperpixel
))
2152 if ((true == last
) && (0x0C & mask
)) {
2169 s32
= ay
[(int)y
] + rv
[(int)v
];
2170 r
= (255 < s32
) ? 255 : ((0 > s32
) ? \
2172 s32
= ay
[(int)y
] - gu
[(int)u
] - \
2174 g
= (255 < s32
) ? 255 : ((0 > s32
) ? \
2176 s32
= ay
[(int)y
] + bu
[(int)u
];
2177 b
= (255 < s32
) ? 255 : ((0 > s32
) ? \
2180 if ((true == last
) && rump
) {
2182 switch (bytesperpixel
- rump
) {
2207 bytesperpixel
- rump
);
2218 p3
+= bytesperpixel
;
2229 SAY("MISTAKE: %i=bytesperpixel\n", bytesperpixel
);
2235 /*****************************************************************************/
2237 debrief(struct easycap
*peasycap
)
2239 if ((struct usb_device
*)NULL
!= peasycap
->pusb_device
) {
2240 check_stk(peasycap
->pusb_device
);
2241 check_saa(peasycap
->pusb_device
);
2242 sayreadonly(peasycap
);
2243 SAY("%i=peasycap->field_fill\n", peasycap
->field_fill
);
2244 SAY("%i=peasycap->field_read\n", peasycap
->field_read
);
2245 SAY("%i=peasycap->frame_fill\n", peasycap
->frame_fill
);
2246 SAY("%i=peasycap->frame_read\n", peasycap
->frame_read
);
2250 /*****************************************************************************/
2252 sayreadonly(struct easycap
*peasycap
)
2255 int got00
, got1F
, got60
, got61
, got62
;
2257 if ((!done
) && ((struct usb_device
*)NULL
!= peasycap
->pusb_device
)) {
2259 got00
= read_saa(peasycap
->pusb_device
, 0x00);
2260 got1F
= read_saa(peasycap
->pusb_device
, 0x1F);
2261 got60
= read_saa(peasycap
->pusb_device
, 0x60);
2262 got61
= read_saa(peasycap
->pusb_device
, 0x61);
2263 got62
= read_saa(peasycap
->pusb_device
, 0x62);
2264 SAY("0x%02X=reg0x00 0x%02X=reg0x1F\n", got00
, got1F
);
2265 SAY("0x%02X=reg0x60 0x%02X=reg0x61 0x%02X=reg0x62\n", \
2266 got60
, got61
, got62
);
2270 /*****************************************************************************/
2271 /*---------------------------------------------------------------------------*/
2273 * SEE CORBET ET AL. "LINUX DEVICE DRIVERS", 3rd EDITION, PAGES 430-434
2275 /*---------------------------------------------------------------------------*/
2276 int easycap_mmap(struct file
*file
, struct vm_area_struct
*pvma
)
2281 pvma
->vm_ops
= &easycap_vm_ops
;
2282 pvma
->vm_flags
|= VM_RESERVED
;
2284 pvma
->vm_private_data
= file
->private_data
;
2285 easycap_vma_open(pvma
);
2288 /*****************************************************************************/
2290 easycap_vma_open(struct vm_area_struct
*pvma
)
2292 struct easycap
*peasycap
;
2294 peasycap
= pvma
->vm_private_data
;
2295 if (NULL
!= peasycap
)
2296 peasycap
->vma_many
++;
2298 JOT(8, "%i=peasycap->vma_many\n", peasycap
->vma_many
);
2302 /*****************************************************************************/
2304 easycap_vma_close(struct vm_area_struct
*pvma
)
2306 struct easycap
*peasycap
;
2308 peasycap
= pvma
->vm_private_data
;
2309 if (NULL
!= peasycap
) {
2310 peasycap
->vma_many
--;
2311 JOT(8, "%i=peasycap->vma_many\n", peasycap
->vma_many
);
2315 /*****************************************************************************/
2317 easycap_vma_fault(struct vm_area_struct
*pvma
, struct vm_fault
*pvmf
)
2322 struct easycap
*peasycap
;
2324 retcode
= VM_FAULT_NOPAGE
;
2325 pbuf
= (void *)NULL
;
2326 page
= (struct page
*)NULL
;
2329 SAY("pvma is NULL\n");
2333 SAY("pvmf is NULL\n");
2337 k
= (pvmf
->pgoff
) / (FRAME_BUFFER_SIZE
/PAGE_SIZE
);
2338 m
= (pvmf
->pgoff
) % (FRAME_BUFFER_SIZE
/PAGE_SIZE
);
2341 JOT(4, "%4i=k, %4i=m\n", k
, m
);
2343 JOT(16, "%4i=k, %4i=m\n", k
, m
);
2345 if ((0 > k
) || (FRAME_BUFFER_MANY
<= k
)) {
2346 SAY("ERROR: buffer index %i out of range\n", k
);
2349 if ((0 > m
) || (FRAME_BUFFER_SIZE
/PAGE_SIZE
<= m
)) {
2350 SAY("ERROR: page number %i out of range\n", m
);
2353 peasycap
= pvma
->vm_private_data
;
2354 if (NULL
== peasycap
) {
2355 SAY("ERROR: peasycap is NULL\n");
2358 mutex_lock(&(peasycap
->mutex_mmap_video
[0]));
2359 /*---------------------------------------------------------------------------*/
2360 pbuf
= peasycap
->frame_buffer
[k
][m
].pgo
;
2362 SAY("ERROR: pbuf is NULL\n");
2365 page
= virt_to_page(pbuf
);
2367 SAY("ERROR: page is NULL\n");
2371 /*---------------------------------------------------------------------------*/
2373 mutex_unlock(&(peasycap
->mutex_mmap_video
[0]));
2375 SAY("ERROR: page is NULL after get_page(page)\n");
2378 retcode
= VM_FAULT_MINOR
;
2382 /*****************************************************************************/
2383 /*---------------------------------------------------------------------------*/
2385 * ON COMPLETION OF A VIDEO URB ITS DATA IS COPIED TO THE FIELD BUFFERS
2386 * PROVIDED peasycap->video_idle IS ZER0. REGARDLESS OF THIS BEING TRUE,
2387 * IT IS RESUBMITTED PROVIDED peasycap->video_isoc_streaming IS NOT ZERO.
2389 * THIS FUNCTION IS AN INTERRUPT SERVICE ROUTINE AND MUST NOT SLEEP.
2391 * INFORMATION ABOUT THE VALIDITY OF THE CONTENTS OF THE FIELD BUFFER ARE
2392 * STORED IN THE TWO-BYTE STATUS PARAMETER
2393 * peasycap->field_buffer[peasycap->field_fill][0].kount
2394 * NOTICE THAT THE INFORMATION IS STORED ONLY WITH PAGE 0 OF THE FIELD BUFFER.
2396 * THE LOWER BYTE CONTAINS THE FIELD PARITY BYTE FURNISHED BY THE SAA7113H
2399 * THE UPPER BYTE IS ZERO IF NO PROBLEMS, OTHERWISE:
2400 * 0 != (kount & 0x8000) => AT LEAST ONE URB COMPLETED WITH ERRORS
2401 * 0 != (kount & 0x4000) => BUFFER HAS TOO MUCH DATA
2402 * 0 != (kount & 0x2000) => BUFFER HAS NOT ENOUGH DATA
2403 * 0 != (kount & 0x0400) => FIELD WAS SUBMITTED BY BRIDGER ROUTINE
2404 * 0 != (kount & 0x0200) => FIELD BUFFER NOT YET CHECKED
2405 * 0 != (kount & 0x0100) => BUFFER HAS TWO EXTRA BYTES - WHY?
2407 /*---------------------------------------------------------------------------*/
2409 easycap_complete(struct urb
*purb
)
2412 struct easycap
*peasycap
;
2413 struct data_buffer
*pfield_buffer
;
2415 int i
, more
, much
, leap
, rc
, last
;
2416 int videofieldamount
;
2417 unsigned int override
;
2418 int framestatus
, framelength
, frameactual
, frameoffset
;
2420 #if defined(BRIDGER)
2421 struct timeval timeval
;
2426 SAY("ERROR: easycap_complete(): purb is NULL\n");
2429 peasycap
= purb
->context
;
2430 if (NULL
== peasycap
) {
2431 SAY("ERROR: easycap_complete(): peasycap is NULL\n");
2435 if (peasycap
->video_eof
)
2438 for (i
= 0; i
< VIDEO_ISOC_BUFFER_MANY
; i
++)
2439 if (purb
->transfer_buffer
== peasycap
->video_isoc_buffer
[i
].pgo
)
2441 JOT(16, "%2i=urb\n", i
);
2442 last
= peasycap
->video_isoc_sequence
;
2443 if ((((VIDEO_ISOC_BUFFER_MANY
- 1) == last
) && \
2445 (((VIDEO_ISOC_BUFFER_MANY
- 1) != last
) && \
2446 ((last
+ 1) != i
))) {
2447 SAY("ERROR: out-of-order urbs %i,%i ... continuing\n", last
, i
);
2449 peasycap
->video_isoc_sequence
= i
;
2451 if (peasycap
->video_idle
) {
2452 JOT(16, "%i=video_idle %i=video_isoc_streaming\n", \
2453 peasycap
->video_idle
, peasycap
->video_isoc_streaming
);
2454 if (peasycap
->video_isoc_streaming
) {
2455 rc
= usb_submit_urb(purb
, GFP_ATOMIC
);
2457 SAY("ERROR: while %i=video_idle, " \
2458 "usb_submit_urb() failed with rc:\n", \
2459 peasycap
->video_idle
);
2498 SAY("0x%08X\n", rc
);
2507 /*---------------------------------------------------------------------------*/
2508 if (FIELD_BUFFER_MANY
<= peasycap
->field_fill
) {
2509 SAY("ERROR: bad peasycap->field_fill\n");
2513 if ((-ESHUTDOWN
== purb
->status
) || (-ENOENT
== purb
->status
)) {
2514 JOT(8, "urb status -ESHUTDOWN or -ENOENT\n");
2518 (peasycap
->field_buffer
[peasycap
->field_fill
][0].kount
) |= 0x8000 ;
2519 SAY("ERROR: bad urb status:\n");
2520 switch (purb
->status
) {
2521 case -EINPROGRESS
: {
2522 SAY("-EINPROGRESS\n"); break;
2525 SAY("-ENOSR\n"); break;
2528 SAY("-EPIPE\n"); break;
2531 SAY("-EOVERFLOW\n"); break;
2534 SAY("-EPROTO\n"); break;
2537 SAY("-EILSEQ\n"); break;
2540 SAY("-ETIMEDOUT\n"); break;
2543 SAY("-EMSGSIZE\n"); break;
2546 SAY("-EOPNOTSUPP\n"); break;
2548 case -EPFNOSUPPORT
: {
2549 SAY("-EPFNOSUPPORT\n"); break;
2551 case -EAFNOSUPPORT
: {
2552 SAY("-EAFNOSUPPORT\n"); break;
2555 SAY("-EADDRINUSE\n"); break;
2557 case -EADDRNOTAVAIL
: {
2558 SAY("-EADDRNOTAVAIL\n"); break;
2561 SAY("-ENOBUFS\n"); break;
2564 SAY("-EISCONN\n"); break;
2567 SAY("-ENOTCONN\n"); break;
2570 SAY("-ESHUTDOWN\n"); break;
2573 SAY("-ENOENT\n"); break;
2576 SAY("-ECONNRESET\n"); break;
2579 SAY("ENOSPC\n"); break;
2582 SAY("unknown error code 0x%08X\n", purb
->status
); break;
2585 /*---------------------------------------------------------------------------*/
2587 for (i
= 0; i
< purb
->number_of_packets
; i
++) {
2588 if (0 != purb
->iso_frame_desc
[i
].status
) {
2589 (peasycap
->field_buffer\
2590 [peasycap
->field_fill
][0].kount
) |= 0x8000 ;
2591 switch (purb
->iso_frame_desc
[i
].status
) {
2593 strcpy(&errbuf
[0], "OK"); break;
2596 strcpy(&errbuf
[0], "-ENOENT"); break;
2598 case -EINPROGRESS
: {
2599 strcpy(&errbuf
[0], "-EINPROGRESS"); break;
2602 strcpy(&errbuf
[0], "-EPROTO"); break;
2605 strcpy(&errbuf
[0], "-EILSEQ"); break;
2608 strcpy(&errbuf
[0], "-ETIME"); break;
2611 strcpy(&errbuf
[0], "-ETIMEDOUT"); break;
2614 strcpy(&errbuf
[0], "-EPIPE"); break;
2617 strcpy(&errbuf
[0], "-ECOMM"); break;
2620 strcpy(&errbuf
[0], "-ENOSR"); break;
2623 strcpy(&errbuf
[0], "-EOVERFLOW"); break;
2626 strcpy(&errbuf
[0], "-EREMOTEIO"); break;
2629 strcpy(&errbuf
[0], "-ENODEV"); break;
2632 strcpy(&errbuf
[0], "-EXDEV"); break;
2635 strcpy(&errbuf
[0], "-EINVAL"); break;
2638 strcpy(&errbuf
[0], "-ECONNRESET"); break;
2641 SAY("ENOSPC\n"); break;
2644 strcpy(&errbuf
[0], "-ESHUTDOWN"); break;
2647 strcpy(&errbuf
[0], "unknown error"); break;
2651 framestatus
= purb
->iso_frame_desc
[i
].status
;
2652 framelength
= purb
->iso_frame_desc
[i
].length
;
2653 frameactual
= purb
->iso_frame_desc
[i
].actual_length
;
2654 frameoffset
= purb
->iso_frame_desc
[i
].offset
;
2656 JOT(16, "frame[%2i]:" \
2661 i
, framestatus
, frameactual
, framelength
, frameoffset
);
2662 if (!purb
->iso_frame_desc
[i
].status
) {
2663 more
= purb
->iso_frame_desc
[i
].actual_length
;
2664 pfield_buffer
= &peasycap
->field_buffer\
2665 [peasycap
->field_fill
][peasycap
->field_page
];
2666 videofieldamount
= (peasycap
->field_page
* \
2668 (int)(pfield_buffer
->pto
- pfield_buffer
->pgo
);
2673 JOT(8, "%4i empty video urb frames\n", mt
);
2676 if (FIELD_BUFFER_MANY
<= peasycap
->field_fill
) {
2677 SAY("ERROR: bad peasycap->field_fill\n");
2680 if (FIELD_BUFFER_SIZE
/PAGE_SIZE
<= \
2681 peasycap
->field_page
) {
2682 SAY("ERROR: bad peasycap->field_page\n");
2685 pfield_buffer
= &peasycap
->field_buffer\
2686 [peasycap
->field_fill
][peasycap
->field_page
];
2687 pu
= (__u8
*)(purb
->transfer_buffer
+ \
2688 purb
->iso_frame_desc
[i
].offset
);
2693 /*--------------------------------------------------------------------------*/
2695 * EIGHT-BYTE END-OF-VIDEOFIELD MARKER.
2696 * NOTE: A SUCCESSION OF URB FRAMES FOLLOWING THIS ARE EMPTY,
2697 * CORRESPONDING TO THE FIELD FLYBACK (VERTICAL BLANKING) PERIOD.
2699 * PROVIDED THE FIELD BUFFER CONTAINS GOOD DATA AS INDICATED BY A ZERO UPPER
2701 * peasycap->field_buffer[peasycap->field_fill][0].kount
2702 * THE CONTENTS OF THE FIELD BUFFER ARE OFFERED TO dqbuf(), field_read IS
2703 * UPDATED AND field_fill IS BUMPED. IF THE FIELD BUFFER CONTAINS BAD DATA
2704 * NOTHING IS OFFERED TO dqbuf().
2706 * THE DECISION ON WHETHER THE PARITY OF THE OFFERED FIELD BUFFER IS RIGHT
2707 * RESTS WITH dqbuf().
2709 /*---------------------------------------------------------------------------*/
2710 if ((8 == more
) || override
) {
2711 if (videofieldamount
> \
2712 peasycap
->videofieldamount
) {
2713 if (2 == videofieldamount
- \
2716 (peasycap
->field_buffer\
2717 [peasycap
->field_fill
]\
2718 [0].kount
) |= 0x0100;
2720 (peasycap
->field_buffer\
2721 [peasycap
->field_fill
]\
2722 [0].kount
) |= 0x4000;
2723 } else if (videofieldamount
< \
2726 (peasycap
->field_buffer\
2727 [peasycap
->field_fill
]\
2728 [0].kount
) |= 0x2000;
2730 if (!(0xFF00 & peasycap
->field_buffer\
2731 [peasycap
->field_fill
]\
2733 (peasycap
->video_junk
)--;
2734 if (-16 > peasycap
->video_junk
)
2735 peasycap
->video_junk
= -16;
2736 peasycap
->field_read
= \
2740 if (FIELD_BUFFER_MANY
<= \
2741 peasycap
->field_fill
)
2742 peasycap
->field_fill
= 0;
2743 peasycap
->field_page
= 0;
2744 pfield_buffer
= &peasycap
->\
2746 [peasycap
->field_fill
]\
2747 [peasycap
->field_page
];
2748 pfield_buffer
->pto
= \
2751 JOT(8, "bumped to: %i=peasycap->" \
2752 "field_fill %i=parity\n", \
2753 peasycap
->field_fill
, \
2754 0x00FF & pfield_buffer
->kount
);
2755 JOT(8, "field buffer %i has %i " \
2756 "bytes fit to be read\n", \
2757 peasycap
->field_read
, \
2759 JOT(8, "wakeup call to wq_video, " \
2760 "%i=field_read %i=field_fill "\
2762 peasycap
->field_read
, \
2763 peasycap
->field_fill
, \
2764 0x00FF & peasycap
->\
2765 field_buffer
[peasycap
->\
2766 field_read
][0].kount
);
2767 wake_up_interruptible(&(peasycap
->\
2769 do_gettimeofday(&peasycap
->timeval7
);
2771 peasycap
->video_junk
++;
2772 JOT(8, "field buffer %i had %i " \
2773 "bytes, now discarded\n", \
2774 peasycap
->field_fill
, \
2777 (peasycap
->field_fill
)++;
2779 if (FIELD_BUFFER_MANY
<= \
2780 peasycap
->field_fill
)
2781 peasycap
->field_fill
= 0;
2782 peasycap
->field_page
= 0;
2784 &peasycap
->field_buffer\
2785 [peasycap
->field_fill
]\
2786 [peasycap
->field_page
];
2787 pfield_buffer
->pto
= \
2790 JOT(8, "bumped to: %i=peasycap->" \
2791 "field_fill %i=parity\n", \
2792 peasycap
->field_fill
, \
2793 0x00FF & pfield_buffer
->kount
);
2796 JOT(8, "end-of-field: received " \
2797 "parity byte 0x%02X\n", \
2800 pfield_buffer
->kount
= 0x0000;
2802 pfield_buffer
->kount
= 0x0001;
2803 JOT(8, "end-of-field: 0x%02X=kount\n",\
2804 0xFF & pfield_buffer
->kount
);
2807 /*---------------------------------------------------------------------------*/
2809 * COPY more BYTES FROM ISOC BUFFER TO FIELD BUFFER
2811 /*---------------------------------------------------------------------------*/
2815 if (FIELD_BUFFER_MANY
<= peasycap
->field_fill
) {
2816 SAY("ERROR: bad peasycap->field_fill\n");
2819 if (FIELD_BUFFER_SIZE
/PAGE_SIZE
<= \
2820 peasycap
->field_page
) {
2821 SAY("ERROR: bad peasycap->field_page\n");
2824 pfield_buffer
= &peasycap
->field_buffer\
2825 [peasycap
->field_fill
][peasycap
->field_page
];
2827 pfield_buffer
= &peasycap
->field_buffer\
2828 [peasycap
->field_fill
]\
2829 [peasycap
->field_page
];
2830 if (PAGE_SIZE
< (pfield_buffer
->pto
- \
2831 pfield_buffer
->pgo
)) {
2832 SAY("ERROR: bad pfield_buffer->pto\n");
2835 if (PAGE_SIZE
== (pfield_buffer
->pto
- \
2836 pfield_buffer
->pgo
)) {
2837 (peasycap
->field_page
)++;
2838 if (FIELD_BUFFER_SIZE
/PAGE_SIZE
<= \
2839 peasycap
->field_page
) {
2840 JOT(16, "wrapping peasycap->" \
2842 peasycap
->field_page
= 0;
2844 pfield_buffer
= &peasycap
->\
2846 [peasycap
->field_fill
]\
2847 [peasycap
->field_page
];
2848 pfield_buffer
->pto
= \
2852 much
= PAGE_SIZE
- (int)(pfield_buffer
->pto
- \
2853 pfield_buffer
->pgo
);
2857 memcpy(pfield_buffer
->pto
, pu
, much
);
2859 (pfield_buffer
->pto
) += much
;
2866 /*---------------------------------------------------------------------------*/
2870 * *** UNDER DEVELOPMENT/TESTING - NOT READY YET! ***
2874 * VIDEOTAPES MAY HAVE BEEN MANUALLY PAUSED AND RESTARTED DURING RECORDING.
2875 * THIS CAUSES LOSS OF SYNC, CONFUSING DOWNSTREAM USERSPACE PROGRAMS WHICH
2876 * MAY INTERPRET THE INTERRUPTION AS A SYMPTOM OF LATENCY. TO OVERCOME THIS
2877 * THE DRIVER BRIDGES THE HIATUS BY SENDING DUMMY VIDEO FRAMES AT ROUGHLY
2878 * THE RIGHT TIME INTERVALS IN THE HOPE OF PERSUADING THE DOWNSTREAM USERSPACE
2879 * PROGRAM TO RESUME NORMAL SERVICE WHEN THE INTERRUPTION IS OVER.
2881 /*---------------------------------------------------------------------------*/
2882 #if defined(BRIDGER)
2883 do_gettimeofday(&timeval
);
2884 if (peasycap
->timeval7
.tv_sec
) {
2885 usec
= 1000000*(timeval
.tv_sec
- peasycap
->timeval7
.tv_sec
) + \
2886 (timeval
.tv_usec
- peasycap
->timeval7
.tv_usec
);
2887 if (usec
> (peasycap
->usec
+ peasycap
->tolerate
)) {
2888 JOT(8, "bridging hiatus\n");
2889 peasycap
->video_junk
= 0;
2890 peasycap
->field_buffer
[peasycap
->field_fill
][0].kount
|= 0x0400;
2892 peasycap
->field_read
= (peasycap
->field_fill
)++;
2894 if (FIELD_BUFFER_MANY
<= peasycap
->field_fill
) \
2895 peasycap
->field_fill
= 0;
2896 peasycap
->field_page
= 0;
2897 pfield_buffer
= &peasycap
->field_buffer\
2898 [peasycap
->field_fill
][peasycap
->field_page
];
2899 pfield_buffer
->pto
= pfield_buffer
->pgo
;
2901 JOT(8, "bumped to: %i=peasycap->field_fill %i=parity\n", \
2902 peasycap
->field_fill
, 0x00FF & pfield_buffer
->kount
);
2903 JOT(8, "field buffer %i has %i bytes to be overwritten\n", \
2904 peasycap
->field_read
, videofieldamount
);
2905 JOT(8, "wakeup call to wq_video, " \
2906 "%i=field_read %i=field_fill %i=parity\n", \
2907 peasycap
->field_read
, peasycap
->field_fill
, \
2909 peasycap
->field_buffer
[peasycap
->field_read
][0].kount
);
2910 wake_up_interruptible(&(peasycap
->wq_video
));
2911 do_gettimeofday(&peasycap
->timeval7
);
2915 /*---------------------------------------------------------------------------*/
2917 * RESUBMIT THIS URB, UNLESS A SEVERE PERSISTENT ERROR CONDITION EXISTS.
2919 * IF THE WAIT QUEUES ARE NOT CLEARED IN RESPONSE TO AN ERROR CONDITION
2920 * THE USERSPACE PROGRAM, E.G. mplayer, MAY HANG ON EXIT. BEWARE.
2922 /*---------------------------------------------------------------------------*/
2923 if (VIDEO_ISOC_BUFFER_MANY
<= peasycap
->video_junk
) {
2924 SAY("easycap driver shutting down on condition green\n");
2925 peasycap
->video_eof
= 1;
2926 peasycap
->audio_eof
= 1;
2927 peasycap
->video_junk
= -VIDEO_ISOC_BUFFER_MANY
;
2928 wake_up_interruptible(&(peasycap
->wq_video
));
2929 wake_up_interruptible(&(peasycap
->wq_audio
));
2932 if (peasycap
->video_isoc_streaming
) {
2933 rc
= usb_submit_urb(purb
, GFP_ATOMIC
);
2935 SAY("ERROR: while %i=video_idle, usb_submit_urb() failed " \
2936 "with rc:\n", peasycap
->video_idle
);
2939 SAY("ENOMEM\n"); break;
2942 SAY("ENODEV\n"); break;
2945 SAY("ENXIO\n"); break;
2948 SAY("EINVAL\n"); break;
2951 SAY("EAGAIN\n"); break;
2954 SAY("EFBIG\n"); break;
2957 SAY("EPIPE\n"); break;
2960 SAY("EMSGSIZE\n"); break;
2963 SAY("ENOSPC\n"); break;
2966 SAY("0x%08X\n", rc
); break;
2973 /*****************************************************************************/
2974 /*---------------------------------------------------------------------------*/
2980 * THIS FUNCTION ASSUMES THAT, ON EACH AND EVERY OCCASION THAT THE DEVICE IS
2981 * PHYSICALLY PLUGGED IN, INTERFACE 0 IS PROBED FIRST.
2982 * IF THIS IS NOT TRUE, THERE IS THE POSSIBILITY OF AN Oops.
2984 * THIS HAS NEVER BEEN A PROBLEM IN PRACTICE, BUT SOMETHING SEEMS WRONG HERE.
2986 /*---------------------------------------------------------------------------*/
2988 easycap_usb_probe(struct usb_interface
*pusb_interface
, \
2989 const struct usb_device_id
*id
)
2991 struct usb_device
*pusb_device
, *pusb_device1
;
2992 struct usb_host_interface
*pusb_host_interface
;
2993 struct usb_endpoint_descriptor
*pepd
;
2994 struct usb_interface_descriptor
*pusb_interface_descriptor
;
2995 struct usb_interface_assoc_descriptor
*pusb_interface_assoc_descriptor
;
2997 static struct easycap
*peasycap
/*=NULL*/;
2998 struct data_urb
*pdata_urb
;
2999 size_t wMaxPacketSize
;
3000 int ISOCwMaxPacketSize
;
3001 int BULKwMaxPacketSize
;
3002 int INTwMaxPacketSize
;
3003 int CTRLwMaxPacketSize
;
3004 __u8 bEndpointAddress
;
3005 __u8 ISOCbEndpointAddress
;
3006 __u8 INTbEndpointAddress
;
3007 int isin
, i
, j
, k
, m
;
3008 __u8 bInterfaceNumber
;
3009 __u8 bInterfaceClass
;
3010 __u8 bInterfaceSubClass
;
3012 int okalt
[8], isokalt
;
3013 int okepn
[8], isokepn
;
3014 int okmps
[8], isokmps
;
3020 if ((struct usb_interface
*)NULL
== pusb_interface
) {
3021 SAY("ERROR: pusb_interface is NULL\n");
3024 /*---------------------------------------------------------------------------*/
3026 * GET POINTER TO STRUCTURE usb_device
3028 /*---------------------------------------------------------------------------*/
3029 pusb_device1
= container_of(pusb_interface
->dev
.parent
, \
3030 struct usb_device
, dev
);
3031 if ((struct usb_device
*)NULL
== pusb_device1
) {
3032 SAY("ERROR: pusb_device1 is NULL\n");
3035 pusb_device
= usb_get_dev(pusb_device1
);
3036 if ((struct usb_device
*)NULL
== pusb_device
) {
3037 SAY("ERROR: pusb_device is NULL\n");
3040 if ((unsigned long int)pusb_device1
!= (unsigned long int)pusb_device
) {
3041 JOT(4, "ERROR: pusb_device1 != pusb_device\n");
3045 JOT(4, "bNumConfigurations=%i\n", pusb_device
->descriptor
.bNumConfigurations
);
3047 /*---------------------------------------------------------------------------*/
3048 pusb_host_interface
= pusb_interface
->cur_altsetting
;
3049 if (NULL
== pusb_host_interface
) {
3050 SAY("ERROR: pusb_host_interface is NULL\n");
3053 pusb_interface_descriptor
= &(pusb_host_interface
->desc
);
3054 if (NULL
== pusb_interface_descriptor
) {
3055 SAY("ERROR: pusb_interface_descriptor is NULL\n");
3058 /*---------------------------------------------------------------------------*/
3060 * GET PROPERTIES OF PROBED INTERFACE
3062 /*---------------------------------------------------------------------------*/
3063 bInterfaceNumber
= pusb_interface_descriptor
->bInterfaceNumber
;
3064 bInterfaceClass
= pusb_interface_descriptor
->bInterfaceClass
;
3065 bInterfaceSubClass
= pusb_interface_descriptor
->bInterfaceSubClass
;
3067 JOT(4, "intf[%i]: pusb_interface->num_altsetting=%i\n", \
3068 bInterfaceNumber
, pusb_interface
->num_altsetting
);
3069 JOT(4, "intf[%i]: pusb_interface->cur_altsetting - " \
3070 "pusb_interface->altsetting=%li\n", bInterfaceNumber
, \
3071 (long int)(pusb_interface
->cur_altsetting
- \
3072 pusb_interface
->altsetting
));
3073 switch (bInterfaceClass
) {
3074 case USB_CLASS_AUDIO
: {
3075 JOT(4, "intf[%i]: bInterfaceClass=0x%02X=USB_CLASS_AUDIO\n", \
3076 bInterfaceNumber
, bInterfaceClass
); break;
3078 case USB_CLASS_VIDEO
: {
3079 JOT(4, "intf[%i]: bInterfaceClass=0x%02X=USB_CLASS_VIDEO\n", \
3080 bInterfaceNumber
, bInterfaceClass
); break;
3082 case USB_CLASS_VENDOR_SPEC
: {
3083 JOT(4, "intf[%i]: bInterfaceClass=0x%02X=USB_CLASS_VENDOR_SPEC\n", \
3084 bInterfaceNumber
, bInterfaceClass
); break;
3089 switch (bInterfaceSubClass
) {
3091 JOT(4, "intf[%i]: bInterfaceSubClass=0x%02X=AUDIOCONTROL\n", \
3092 bInterfaceNumber
, bInterfaceSubClass
); break;
3095 JOT(4, "intf[%i]: bInterfaceSubClass=0x%02X=AUDIOSTREAMING\n", \
3096 bInterfaceNumber
, bInterfaceSubClass
); break;
3099 JOT(4, "intf[%i]: bInterfaceSubClass=0x%02X=MIDISTREAMING\n", \
3100 bInterfaceNumber
, bInterfaceSubClass
); break;
3105 /*---------------------------------------------------------------------------*/
3106 pusb_interface_assoc_descriptor
= pusb_interface
->intf_assoc
;
3107 if (NULL
!= pusb_interface_assoc_descriptor
) {
3108 JOT(4, "intf[%i]: bFirstInterface=0x%02X bInterfaceCount=0x%02X\n", \
3110 pusb_interface_assoc_descriptor
->bFirstInterface
, \
3111 pusb_interface_assoc_descriptor
->bInterfaceCount
);
3113 JOT(4, "intf[%i]: pusb_interface_assoc_descriptor is NULL\n", \
3116 /*---------------------------------------------------------------------------*/
3118 * A NEW struct easycap IS ALWAYS ALLOCATED WHEN INTERFACE 0 IS PROBED.
3119 * IT IS NOT POSSIBLE HERE TO FREE ANY EXISTING struct easycap. THIS
3120 * SHOULD HAVE BEEN DONE BY easycap_delete() WHEN THE DEVICE WAS PHYSICALLY
3123 /*---------------------------------------------------------------------------*/
3124 if (0 == bInterfaceNumber
) {
3125 peasycap
= kzalloc(sizeof(struct easycap
), GFP_KERNEL
);
3126 if (NULL
== peasycap
) {
3127 SAY("ERROR: Could not allocate peasycap\n");
3130 peasycap
->allocation_video_struct
= sizeof(struct easycap
);
3131 peasycap
->allocation_video_page
= 0;
3132 peasycap
->allocation_video_urb
= 0;
3133 peasycap
->allocation_audio_struct
= 0;
3134 peasycap
->allocation_audio_page
= 0;
3135 peasycap
->allocation_audio_urb
= 0;
3137 /*---------------------------------------------------------------------------*/
3139 * INITIALIZE THE NEW easycap STRUCTURE.
3140 * NO PARAMETERS ARE SPECIFIED HERE REQUIRING THE SETTING OF REGISTERS.
3141 * THAT IS DONE FIRST BY easycap_open() AND LATER BY easycap_ioctl().
3143 /*---------------------------------------------------------------------------*/
3144 peasycap
->pusb_device
= pusb_device
;
3145 peasycap
->pusb_interface
= pusb_interface
;
3147 kref_init(&peasycap
->kref
);
3148 JOT(8, "intf[%i]: after kref_init(..._video) " \
3149 "%i=peasycap->kref.refcount.counter\n", \
3150 bInterfaceNumber
, peasycap
->kref
.refcount
.counter
);
3152 init_waitqueue_head(&(peasycap
->wq_video
));
3153 init_waitqueue_head(&(peasycap
->wq_audio
));
3155 mutex_init(&(peasycap
->mutex_timeval0
));
3156 mutex_init(&(peasycap
->mutex_timeval1
));
3158 for (k
= 0; k
< FRAME_BUFFER_MANY
; k
++)
3159 mutex_init(&(peasycap
->mutex_mmap_video
[k
]));
3162 peasycap
->microphone
= false;
3164 peasycap
->video_interface
= -1;
3165 peasycap
->video_altsetting_on
= -1;
3166 peasycap
->video_altsetting_off
= -1;
3167 peasycap
->video_endpointnumber
= -1;
3168 peasycap
->video_isoc_maxframesize
= -1;
3169 peasycap
->video_isoc_buffer_size
= -1;
3171 peasycap
->audio_interface
= -1;
3172 peasycap
->audio_altsetting_on
= -1;
3173 peasycap
->audio_altsetting_off
= -1;
3174 peasycap
->audio_endpointnumber
= -1;
3175 peasycap
->audio_isoc_maxframesize
= -1;
3176 peasycap
->audio_isoc_buffer_size
= -1;
3178 peasycap
->frame_buffer_many
= FRAME_BUFFER_MANY
;
3180 if ((struct mutex
*)NULL
== &(peasycap
->mutex_mmap_video
[0])) {
3181 SAY("ERROR: &(peasycap->mutex_mmap_video[%i]) is NULL\n", 0);
3184 /*---------------------------------------------------------------------------*/
3186 * DYNAMICALLY FILL IN THE AVAILABLE FORMATS.
3188 /*---------------------------------------------------------------------------*/
3189 rc
= fillin_formats();
3191 SAY("ERROR: fillin_formats() returned %i\n", rc
);
3194 JOT(4, "%i formats available\n", rc
);
3196 /*---------------------------------------------------------------------------*/
3197 if ((struct easycap
*)NULL
== peasycap
) {
3198 SAY("ERROR: peasycap is NULL " \
3199 "when probing interface %i\n", \
3204 JOT(8, "kref_get() with %i=peasycap->kref.refcount.counter\n", \
3205 (int)peasycap
->kref
.refcount
.counter
);
3206 kref_get(&peasycap
->kref
);
3208 /*---------------------------------------------------------------------------*/
3209 if ((USB_CLASS_VIDEO
== bInterfaceClass
) || \
3210 (USB_CLASS_VENDOR_SPEC
== bInterfaceClass
)) {
3211 if (-1 == peasycap
->video_interface
) {
3212 peasycap
->video_interface
= bInterfaceNumber
;
3213 JOT(4, "setting peasycap->video_interface=%i\n", \
3214 peasycap
->video_interface
);
3216 if (peasycap
->video_interface
!= bInterfaceNumber
) {
3217 SAY("ERROR: attempting to reset " \
3218 "peasycap->video_interface\n");
3219 SAY("...... continuing with " \
3220 "%i=peasycap->video_interface\n", \
3221 peasycap
->video_interface
);
3224 } else if ((USB_CLASS_AUDIO
== bInterfaceClass
) && \
3225 (0x02 == bInterfaceSubClass
)) {
3226 if (-1 == peasycap
->audio_interface
) {
3227 peasycap
->audio_interface
= bInterfaceNumber
;
3228 JOT(4, "setting peasycap->audio_interface=%i\n", \
3229 peasycap
->audio_interface
);
3231 if (peasycap
->audio_interface
!= bInterfaceNumber
) {
3232 SAY("ERROR: attempting to reset " \
3233 "peasycap->audio_interface\n");
3234 SAY("...... continuing with " \
3235 "%i=peasycap->audio_interface\n", \
3236 peasycap
->audio_interface
);
3240 /*---------------------------------------------------------------------------*/
3242 * INVESTIGATE ALL ALTSETTINGS.
3243 * DONE IN DETAIL BECAUSE USB DEVICE 05e1:0408 HAS DISPARATE INCARNATIONS.
3245 /*---------------------------------------------------------------------------*/
3250 for (i
= 0; i
< pusb_interface
->num_altsetting
; i
++) {
3251 pusb_host_interface
= &(pusb_interface
->altsetting
[i
]);
3252 if ((struct usb_host_interface
*)NULL
== pusb_host_interface
) {
3253 SAY("ERROR: pusb_host_interface is NULL\n");
3256 pusb_interface_descriptor
= &(pusb_host_interface
->desc
);
3257 if ((struct usb_interface_descriptor
*)NULL
== \
3258 pusb_interface_descriptor
) {
3259 SAY("ERROR: pusb_interface_descriptor is NULL\n");
3263 JOT(4, "intf[%i]alt[%i]: desc.bDescriptorType=0x%02X\n", \
3264 bInterfaceNumber
, i
, pusb_interface_descriptor
->bDescriptorType
);
3265 JOT(4, "intf[%i]alt[%i]: desc.bInterfaceNumber=0x%02X\n", \
3266 bInterfaceNumber
, i
, pusb_interface_descriptor
->bInterfaceNumber
);
3267 JOT(4, "intf[%i]alt[%i]: desc.bAlternateSetting=0x%02X\n", \
3268 bInterfaceNumber
, i
, pusb_interface_descriptor
->bAlternateSetting
);
3269 JOT(4, "intf[%i]alt[%i]: desc.bNumEndpoints=0x%02X\n", \
3270 bInterfaceNumber
, i
, pusb_interface_descriptor
->bNumEndpoints
);
3271 JOT(4, "intf[%i]alt[%i]: desc.bInterfaceClass=0x%02X\n", \
3272 bInterfaceNumber
, i
, pusb_interface_descriptor
->bInterfaceClass
);
3273 JOT(4, "intf[%i]alt[%i]: desc.bInterfaceSubClass=0x%02X\n", \
3274 bInterfaceNumber
, i
, pusb_interface_descriptor
->bInterfaceSubClass
);
3275 JOT(4, "intf[%i]alt[%i]: desc.bInterfaceProtocol=0x%02X\n", \
3276 bInterfaceNumber
, i
, pusb_interface_descriptor
->bInterfaceProtocol
);
3277 JOT(4, "intf[%i]alt[%i]: desc.iInterface=0x%02X\n", \
3278 bInterfaceNumber
, i
, pusb_interface_descriptor
->iInterface
);
3280 ISOCwMaxPacketSize
= -1;
3281 BULKwMaxPacketSize
= -1;
3282 INTwMaxPacketSize
= -1;
3283 CTRLwMaxPacketSize
= -1;
3284 ISOCbEndpointAddress
= 0;
3285 INTbEndpointAddress
= 0;
3287 if (0 == pusb_interface_descriptor
->bNumEndpoints
)
3288 JOT(4, "intf[%i]alt[%i] has no endpoints\n", \
3289 bInterfaceNumber
, i
);
3290 /*---------------------------------------------------------------------------*/
3291 for (j
= 0; j
< pusb_interface_descriptor
->bNumEndpoints
; j
++) {
3292 pepd
= &(pusb_host_interface
->endpoint
[j
].desc
);
3293 if ((struct usb_endpoint_descriptor
*)NULL
== pepd
) {
3294 SAY("ERROR: pepd is NULL.\n");
3295 SAY("...... skipping\n");
3298 wMaxPacketSize
= le16_to_cpu(pepd
->wMaxPacketSize
);
3299 bEndpointAddress
= pepd
->bEndpointAddress
;
3301 JOT(4, "intf[%i]alt[%i]end[%i]: bEndpointAddress=0x%X\n", \
3302 bInterfaceNumber
, i
, j
, \
3303 pepd
->bEndpointAddress
);
3304 JOT(4, "intf[%i]alt[%i]end[%i]: bmAttributes=0x%X\n", \
3305 bInterfaceNumber
, i
, j
, \
3306 pepd
->bmAttributes
);
3307 JOT(4, "intf[%i]alt[%i]end[%i]: wMaxPacketSize=%i\n", \
3308 bInterfaceNumber
, i
, j
, \
3309 pepd
->wMaxPacketSize
);
3310 JOT(4, "intf[%i]alt[%i]end[%i]: bInterval=%i\n",
3311 bInterfaceNumber
, i
, j
, \
3314 if (pepd
->bEndpointAddress
& USB_DIR_IN
) {
3315 JOT(4, "intf[%i]alt[%i]end[%i] is an IN endpoint\n",\
3316 bInterfaceNumber
, i
, j
);
3319 JOT(4, "intf[%i]alt[%i]end[%i] is an OUT endpoint\n",\
3320 bInterfaceNumber
, i
, j
);
3321 SAY("ERROR: OUT endpoint unexpected\n");
3322 SAY("...... continuing\n");
3325 if ((pepd
->bmAttributes
& \
3326 USB_ENDPOINT_XFERTYPE_MASK
) == \
3327 USB_ENDPOINT_XFER_ISOC
) {
3328 JOT(4, "intf[%i]alt[%i]end[%i] is an ISOC endpoint\n",\
3329 bInterfaceNumber
, i
, j
);
3331 switch (bInterfaceClass
) {
3332 case USB_CLASS_VIDEO
:
3333 case USB_CLASS_VENDOR_SPEC
: {
3336 "peasycap is NULL\n");
3339 if (pepd
->wMaxPacketSize
) {
3351 bEndpointAddress
& \
3370 if (-1 == peasycap
->\
3371 video_altsetting_off
) {
3373 video_altsetting_off
=\
3375 JOT(4, "%i=video_" \
3379 video_altsetting_off
);
3381 SAY("ERROR: peasycap" \
3382 "->video_altsetting_" \
3383 "off already set\n");
3385 "continuing with " \
3386 "%i=peasycap->video_" \
3387 "altsetting_off\n", \
3389 video_altsetting_off
);
3394 case USB_CLASS_AUDIO
: {
3395 if (0x02 != bInterfaceSubClass
)
3399 "peasycap is NULL\n");
3402 if (pepd
->wMaxPacketSize
) {
3404 okalt
[isokalt
] = i
;
3414 bEndpointAddress
& \
3433 if (-1 == peasycap
->\
3434 audio_altsetting_off
) {
3436 audio_altsetting_off
=\
3438 JOT(4, "%i=audio_" \
3442 audio_altsetting_off
);
3444 SAY("ERROR: peasycap" \
3445 "->audio_altsetting_" \
3446 "off already set\n");
3448 "continuing with " \
3450 audio_altsetting_" \
3453 audio_altsetting_off
);
3462 } else if ((pepd
->bmAttributes
& \
3463 USB_ENDPOINT_XFERTYPE_MASK
) ==\
3464 USB_ENDPOINT_XFER_BULK
) {
3465 JOT(4, "intf[%i]alt[%i]end[%i] is a BULK endpoint\n",\
3466 bInterfaceNumber
, i
, j
);
3467 } else if ((pepd
->bmAttributes
& \
3468 USB_ENDPOINT_XFERTYPE_MASK
) ==\
3469 USB_ENDPOINT_XFER_INT
) {
3470 JOT(4, "intf[%i]alt[%i]end[%i] is an INT endpoint\n",\
3471 bInterfaceNumber
, i
, j
);
3473 JOT(4, "intf[%i]alt[%i]end[%i] is a CTRL endpoint\n",\
3474 bInterfaceNumber
, i
, j
);
3476 if (0 == pepd
->wMaxPacketSize
) {
3477 JOT(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 JOT(4, "initialization begins for interface %i\n", \
3489 pusb_interface_descriptor
->bInterfaceNumber
);
3490 switch (bInterfaceNumber
) {
3491 /*---------------------------------------------------------------------------*/
3493 * INTERFACE 0 IS THE VIDEO INTERFACE
3495 /*---------------------------------------------------------------------------*/
3498 SAY("MISTAKE: peasycap is NULL\n");
3502 SAY("ERROR: no viable video_altsetting_on\n");
3505 peasycap
->video_altsetting_on
= okalt
[isokalt
- 1];
3506 JOT(4, "%i=video_altsetting_on <====\n", \
3507 peasycap
->video_altsetting_on
);
3510 SAY("ERROR: no viable video_endpointnumber\n");
3513 peasycap
->video_endpointnumber
= okepn
[isokepn
- 1];
3514 JOT(4, "%i=video_endpointnumber\n", \
3515 peasycap
->video_endpointnumber
);
3518 SAY("ERROR: no viable video_maxpacketsize\n");
3520 /*---------------------------------------------------------------------------*/
3522 * DECIDE THE VIDEO STREAMING PARAMETERS
3524 /*---------------------------------------------------------------------------*/
3526 maxpacketsize
= okmps
[isokmps
- 1] - 1024;
3527 if (USB_2_0_MAXPACKETSIZE
> maxpacketsize
) {
3528 peasycap
->video_isoc_maxframesize
= maxpacketsize
;
3530 peasycap
->video_isoc_maxframesize
= \
3531 USB_2_0_MAXPACKETSIZE
;
3533 JOT(4, "%i=video_isoc_maxframesize\n", \
3534 peasycap
->video_isoc_maxframesize
);
3535 if (0 >= peasycap
->video_isoc_maxframesize
) {
3536 SAY("ERROR: bad video_isoc_maxframesize\n");
3539 peasycap
->video_isoc_framesperdesc
= VIDEO_ISOC_FRAMESPERDESC
;
3540 JOT(4, "%i=video_isoc_framesperdesc\n", \
3541 peasycap
->video_isoc_framesperdesc
);
3542 if (0 >= peasycap
->video_isoc_framesperdesc
) {
3543 SAY("ERROR: bad video_isoc_framesperdesc\n");
3546 peasycap
->video_isoc_buffer_size
= \
3547 peasycap
->video_isoc_maxframesize
* \
3548 peasycap
->video_isoc_framesperdesc
;
3549 JOT(4, "%i=video_isoc_buffer_size\n", \
3550 peasycap
->video_isoc_buffer_size
);
3551 if ((PAGE_SIZE
<< VIDEO_ISOC_ORDER
) < \
3552 peasycap
->video_isoc_buffer_size
) {
3554 "peasycap->video_isoc_buffer_size too big\n");
3558 /*---------------------------------------------------------------------------*/
3559 if (-1 == peasycap
->video_interface
) {
3560 SAY("MISTAKE: video_interface is unset\n");
3563 if (-1 == peasycap
->video_altsetting_on
) {
3564 SAY("MISTAKE: video_altsetting_on is unset\n");
3567 if (-1 == peasycap
->video_altsetting_off
) {
3568 SAY("MISTAKE: video_interface_off is unset\n");
3571 if (-1 == peasycap
->video_endpointnumber
) {
3572 SAY("MISTAKE: video_endpointnumber is unset\n");
3575 if (-1 == peasycap
->video_isoc_maxframesize
) {
3576 SAY("MISTAKE: video_isoc_maxframesize is unset\n");
3579 if (-1 == peasycap
->video_isoc_buffer_size
) {
3580 SAY("MISTAKE: video_isoc_buffer_size is unset\n");
3583 /*---------------------------------------------------------------------------*/
3585 * ALLOCATE MEMORY FOR VIDEO BUFFERS. LISTS MUST BE INITIALIZED FIRST.
3587 /*---------------------------------------------------------------------------*/
3588 INIT_LIST_HEAD(&(peasycap
->urb_video_head
));
3589 peasycap
->purb_video_head
= &(peasycap
->urb_video_head
);
3590 /*---------------------------------------------------------------------------*/
3591 JOT(4, "allocating %i frame buffers of size %li\n", \
3592 FRAME_BUFFER_MANY
, (long int)FRAME_BUFFER_SIZE
);
3593 JOT(4, ".... each scattered over %li pages\n", \
3594 FRAME_BUFFER_SIZE
/PAGE_SIZE
);
3596 for (k
= 0; k
< FRAME_BUFFER_MANY
; k
++) {
3597 for (m
= 0; m
< FRAME_BUFFER_SIZE
/PAGE_SIZE
; m
++) {
3598 if ((void *)NULL
!= peasycap
->frame_buffer
[k
][m
].pgo
)
3599 SAY("attempting to reallocate frame " \
3602 pbuf
= (void *)__get_free_page(GFP_KERNEL
);
3603 if ((void *)NULL
== pbuf
) {
3604 SAY("ERROR: Could not allocate frame "\
3605 "buffer %i page %i\n", k
, m
);
3608 peasycap
->allocation_video_page
+= 1;
3609 peasycap
->frame_buffer
[k
][m
].pgo
= pbuf
;
3611 peasycap
->frame_buffer
[k
][m
].pto
= \
3612 peasycap
->frame_buffer
[k
][m
].pgo
;
3616 peasycap
->frame_fill
= 0;
3617 peasycap
->frame_read
= 0;
3618 JOT(4, "allocation of frame buffers done: %i pages\n", k
* \
3620 /*---------------------------------------------------------------------------*/
3621 JOT(4, "allocating %i field buffers of size %li\n", \
3622 FIELD_BUFFER_MANY
, (long int)FIELD_BUFFER_SIZE
);
3623 JOT(4, ".... each scattered over %li pages\n", \
3624 FIELD_BUFFER_SIZE
/PAGE_SIZE
);
3626 for (k
= 0; k
< FIELD_BUFFER_MANY
; k
++) {
3627 for (m
= 0; m
< FIELD_BUFFER_SIZE
/PAGE_SIZE
; m
++) {
3628 if ((void *)NULL
!= peasycap
->field_buffer
[k
][m
].pgo
) {
3629 SAY("ERROR: attempting to reallocate " \
3632 pbuf
= (void *) __get_free_page(GFP_KERNEL
);
3633 if ((void *)NULL
== pbuf
) {
3634 SAY("ERROR: Could not allocate field" \
3635 " buffer %i page %i\n", k
, m
);
3639 peasycap
->allocation_video_page
+= 1;
3640 peasycap
->field_buffer
[k
][m
].pgo
= pbuf
;
3642 peasycap
->field_buffer
[k
][m
].pto
= \
3643 peasycap
->field_buffer
[k
][m
].pgo
;
3645 peasycap
->field_buffer
[k
][0].kount
= 0x0200;
3647 peasycap
->field_fill
= 0;
3648 peasycap
->field_page
= 0;
3649 peasycap
->field_read
= 0;
3650 JOT(4, "allocation of field buffers done: %i pages\n", k
* \
3652 /*---------------------------------------------------------------------------*/
3653 JOT(4, "allocating %i isoc video buffers of size %i\n", \
3654 VIDEO_ISOC_BUFFER_MANY
, \
3655 peasycap
->video_isoc_buffer_size
);
3656 JOT(4, ".... each occupying contiguous memory pages\n");
3658 for (k
= 0; k
< VIDEO_ISOC_BUFFER_MANY
; k
++) {
3659 pbuf
= (void *)__get_free_pages(GFP_KERNEL
, VIDEO_ISOC_ORDER
);
3661 SAY("ERROR: Could not allocate isoc video buffer " \
3665 peasycap
->allocation_video_page
+= \
3666 ((unsigned int)(0x01 << VIDEO_ISOC_ORDER
));
3668 peasycap
->video_isoc_buffer
[k
].pgo
= pbuf
;
3669 peasycap
->video_isoc_buffer
[k
].pto
= pbuf
+ \
3670 peasycap
->video_isoc_buffer_size
;
3671 peasycap
->video_isoc_buffer
[k
].kount
= k
;
3673 JOT(4, "allocation of isoc video buffers done: %i pages\n", \
3674 k
* (0x01 << VIDEO_ISOC_ORDER
));
3675 /*---------------------------------------------------------------------------*/
3677 * ALLOCATE AND INITIALIZE MULTIPLE struct urb ...
3679 /*---------------------------------------------------------------------------*/
3680 JOT(4, "allocating %i struct urb.\n", VIDEO_ISOC_BUFFER_MANY
);
3681 JOT(4, "using %i=peasycap->video_isoc_framesperdesc\n", \
3682 peasycap
->video_isoc_framesperdesc
);
3683 JOT(4, "using %i=peasycap->video_isoc_maxframesize\n", \
3684 peasycap
->video_isoc_maxframesize
);
3685 JOT(4, "using %i=peasycap->video_isoc_buffer_sizen", \
3686 peasycap
->video_isoc_buffer_size
);
3688 for (k
= 0; k
< VIDEO_ISOC_BUFFER_MANY
; k
++) {
3689 purb
= usb_alloc_urb(peasycap
->video_isoc_framesperdesc
, \
3692 SAY("ERROR: usb_alloc_urb returned NULL for buffer " \
3696 peasycap
->allocation_video_urb
+= 1;
3697 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
3698 pdata_urb
= kzalloc(sizeof(struct data_urb
), GFP_KERNEL
);
3699 if (NULL
== pdata_urb
) {
3700 SAY("ERROR: Could not allocate struct data_urb.\n");
3703 peasycap
->allocation_video_struct
+= \
3704 sizeof(struct data_urb
);
3706 pdata_urb
->purb
= purb
;
3707 pdata_urb
->isbuf
= k
;
3708 pdata_urb
->length
= 0;
3709 list_add_tail(&(pdata_urb
->list_head
), \
3710 peasycap
->purb_video_head
);
3711 /*---------------------------------------------------------------------------*/
3713 * ... AND INITIALIZE THEM
3715 /*---------------------------------------------------------------------------*/
3717 JOT(4, "initializing video urbs thus:\n");
3718 JOT(4, " purb->interval = 1;\n");
3719 JOT(4, " purb->dev = peasycap->pusb_device;\n");
3720 JOT(4, " purb->pipe = usb_rcvisocpipe" \
3721 "(peasycap->pusb_device,%i);\n", \
3722 peasycap
->video_endpointnumber
);
3723 JOT(4, " purb->transfer_flags = URB_ISO_ASAP;\n");
3724 JOT(4, " purb->transfer_buffer = peasycap->" \
3725 "video_isoc_buffer[.].pgo;\n");
3726 JOT(4, " purb->transfer_buffer_length = %i;\n", \
3727 peasycap
->video_isoc_buffer_size
);
3728 JOT(4, " purb->complete = easycap_complete;\n");
3729 JOT(4, " purb->context = peasycap;\n");
3730 JOT(4, " purb->start_frame = 0;\n");
3731 JOT(4, " purb->number_of_packets = %i;\n", \
3732 peasycap
->video_isoc_framesperdesc
);
3733 JOT(4, " for (j = 0; j < %i; j++)\n", \
3734 peasycap
->video_isoc_framesperdesc
);
3736 JOT(4, " purb->iso_frame_desc[j].offset = j*%i;\n",\
3737 peasycap
->video_isoc_maxframesize
);
3738 JOT(4, " purb->iso_frame_desc[j].length = %i;\n", \
3739 peasycap
->video_isoc_maxframesize
);
3744 purb
->dev
= peasycap
->pusb_device
;
3745 purb
->pipe
= usb_rcvisocpipe(peasycap
->pusb_device
, \
3746 peasycap
->video_endpointnumber
);
3747 purb
->transfer_flags
= URB_ISO_ASAP
;
3748 purb
->transfer_buffer
= peasycap
->video_isoc_buffer
[k
].pgo
;
3749 purb
->transfer_buffer_length
= \
3750 peasycap
->video_isoc_buffer_size
;
3751 purb
->complete
= easycap_complete
;
3752 purb
->context
= peasycap
;
3753 purb
->start_frame
= 0;
3754 purb
->number_of_packets
= peasycap
->video_isoc_framesperdesc
;
3755 for (j
= 0; j
< peasycap
->video_isoc_framesperdesc
; j
++) {
3756 purb
->iso_frame_desc
[j
].offset
= j
* \
3757 peasycap
->video_isoc_maxframesize
;
3758 purb
->iso_frame_desc
[j
].length
= \
3759 peasycap
->video_isoc_maxframesize
;
3762 JOT(4, "allocation of %i struct urb done.\n", k
);
3763 /*--------------------------------------------------------------------------*/
3765 * SAVE POINTER peasycap IN THIS INTERFACE.
3767 /*--------------------------------------------------------------------------*/
3768 usb_set_intfdata(pusb_interface
, peasycap
);
3769 /*--------------------------------------------------------------------------*/
3771 * THE VIDEO DEVICE CAN BE REGISTERED NOW, AS IT IS READY.
3773 /*--------------------------------------------------------------------------*/
3774 #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
3775 if (0 != (usb_register_dev(pusb_interface
, &easycap_class
))) {
3776 err("Not able to get a minor for this device");
3777 usb_set_intfdata(pusb_interface
, NULL
);
3780 (peasycap
->registered_video
)++;
3781 SAY("easycap attached to minor #%d\n", pusb_interface
->minor
);
3783 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
3785 pvideo_device
= (struct video_device
*)\
3786 kzalloc(sizeof(struct video_device
), GFP_KERNEL
);
3787 if ((struct video_device
*)NULL
== pvideo_device
) {
3788 SAY("ERROR: Could not allocate structure video_device\n");
3791 if (VIDEO_DEVICE_MANY
<= video_device_many
) {
3792 SAY("ERROR: Too many /dev/videos\n");
3795 pvideo_array
[video_device_many
] = pvideo_device
; video_device_many
++;
3797 strcpy(&pvideo_device
->name
[0], "easycapdc60");
3798 #if defined(EASYCAP_NEEDS_V4L2_FOPS)
3799 pvideo_device
->fops
= &v4l2_fops
;
3801 pvideo_device
->fops
= &easycap_fops
;
3802 #endif /*EASYCAP_NEEDS_V4L2_FOPS*/
3803 pvideo_device
->minor
= -1;
3804 pvideo_device
->release
= (void *)(&videodev_release
);
3806 video_set_drvdata(pvideo_device
, (void *)peasycap
);
3808 rc
= video_register_device(pvideo_device
, VFL_TYPE_GRABBER
, -1);
3810 err("Not able to register with videodev");
3811 videodev_release(pvideo_device
);
3814 peasycap
->pvideo_device
= pvideo_device
;
3815 (peasycap
->registered_video
)++;
3816 JOT(4, "registered with videodev: %i=minor\n", \
3817 pvideo_device
->minor
);
3819 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
3820 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
3823 /*--------------------------------------------------------------------------*/
3825 * INTERFACE 1 IS THE AUDIO CONTROL INTERFACE
3826 * INTERFACE 2 IS THE AUDIO STREAMING INTERFACE
3828 /*--------------------------------------------------------------------------*/
3830 /*--------------------------------------------------------------------------*/
3832 * SAVE POINTER peasycap IN INTERFACE 1
3834 /*--------------------------------------------------------------------------*/
3835 usb_set_intfdata(pusb_interface
, peasycap
);
3836 JOT(4, "no initialization required for interface %i\n", \
3837 pusb_interface_descriptor
->bInterfaceNumber
);
3840 /*--------------------------------------------------------------------------*/
3843 SAY("MISTAKE: peasycap is NULL\n");
3847 SAY("ERROR: no viable audio_altsetting_on\n");
3850 peasycap
->audio_altsetting_on
= okalt
[isokalt
- 1];
3851 JOT(4, "%i=audio_altsetting_on <====\n", \
3852 peasycap
->audio_altsetting_on
);
3855 SAY("ERROR: no viable audio_endpointnumber\n");
3858 peasycap
->audio_endpointnumber
= okepn
[isokepn
- 1];
3859 JOT(4, "%i=audio_endpointnumber\n", \
3860 peasycap
->audio_endpointnumber
);
3863 SAY("ERROR: no viable audio_maxpacketsize\n");
3866 peasycap
->audio_isoc_maxframesize
= okmps
[isokmps
- 1];
3867 JOT(4, "%i=audio_isoc_maxframesize\n", \
3868 peasycap
->audio_isoc_maxframesize
);
3869 if (0 >= peasycap
->audio_isoc_maxframesize
) {
3870 SAY("ERROR: bad audio_isoc_maxframesize\n");
3873 if (9 == peasycap
->audio_isoc_maxframesize
) {
3874 peasycap
->ilk
|= 0x02;
3875 SAY("hardware is FOUR-CVBS\n");
3876 peasycap
->microphone
= true;
3877 peasycap
->audio_pages_per_fragment
= 4;
3878 } else if (256 == peasycap
->audio_isoc_maxframesize
) {
3879 peasycap
->ilk
&= ~0x02;
3880 SAY("hardware is CVBS+S-VIDEO\n");
3881 peasycap
->microphone
= false;
3882 peasycap
->audio_pages_per_fragment
= 4;
3884 SAY("hardware is unidentified:\n");
3885 SAY("%i=audio_isoc_maxframesize\n", \
3886 peasycap
->audio_isoc_maxframesize
);
3890 peasycap
->audio_bytes_per_fragment
= \
3891 peasycap
->audio_pages_per_fragment
* \
3893 peasycap
->audio_buffer_page_many
= (AUDIO_FRAGMENT_MANY
* \
3894 peasycap
->audio_pages_per_fragment
);
3896 JOT(4, "%6i=AUDIO_FRAGMENT_MANY\n", AUDIO_FRAGMENT_MANY
);
3897 JOT(4, "%6i=audio_pages_per_fragment\n", \
3898 peasycap
->audio_pages_per_fragment
);
3899 JOT(4, "%6i=audio_bytes_per_fragment\n", \
3900 peasycap
->audio_bytes_per_fragment
);
3901 JOT(4, "%6i=audio_buffer_page_many\n", \
3902 peasycap
->audio_buffer_page_many
);
3904 peasycap
->audio_isoc_framesperdesc
= 128;
3906 JOT(4, "%i=audio_isoc_framesperdesc\n", \
3907 peasycap
->audio_isoc_framesperdesc
);
3908 if (0 >= peasycap
->audio_isoc_framesperdesc
) {
3909 SAY("ERROR: bad audio_isoc_framesperdesc\n");
3913 peasycap
->audio_isoc_buffer_size
= \
3914 peasycap
->audio_isoc_maxframesize
* \
3915 peasycap
->audio_isoc_framesperdesc
;
3916 JOT(4, "%i=audio_isoc_buffer_size\n", \
3917 peasycap
->audio_isoc_buffer_size
);
3918 if (AUDIO_ISOC_BUFFER_SIZE
< \
3919 peasycap
->audio_isoc_buffer_size
) {
3920 SAY("MISTAKE: audio_isoc_buffer_size bigger "
3921 "than %li=AUDIO_ISOC_BUFFER_SIZE\n", \
3922 AUDIO_ISOC_BUFFER_SIZE
);
3927 if (-1 == peasycap
->audio_interface
) {
3928 SAY("MISTAKE: audio_interface is unset\n");
3931 if (-1 == peasycap
->audio_altsetting_on
) {
3932 SAY("MISTAKE: audio_altsetting_on is unset\n");
3935 if (-1 == peasycap
->audio_altsetting_off
) {
3936 SAY("MISTAKE: audio_interface_off is unset\n");
3939 if (-1 == peasycap
->audio_endpointnumber
) {
3940 SAY("MISTAKE: audio_endpointnumber is unset\n");
3943 if (-1 == peasycap
->audio_isoc_maxframesize
) {
3944 SAY("MISTAKE: audio_isoc_maxframesize is unset\n");
3947 if (-1 == peasycap
->audio_isoc_buffer_size
) {
3948 SAY("MISTAKE: audio_isoc_buffer_size is unset\n");
3951 /*---------------------------------------------------------------------------*/
3953 * ALLOCATE MEMORY FOR AUDIO BUFFERS. LISTS MUST BE INITIALIZED FIRST.
3955 /*---------------------------------------------------------------------------*/
3956 INIT_LIST_HEAD(&(peasycap
->urb_audio_head
));
3957 peasycap
->purb_audio_head
= &(peasycap
->urb_audio_head
);
3959 JOT(4, "allocating an audio buffer\n");
3960 JOT(4, ".... scattered over %i pages\n", \
3961 peasycap
->audio_buffer_page_many
);
3963 for (k
= 0; k
< peasycap
->audio_buffer_page_many
; k
++) {
3964 if ((void *)NULL
!= peasycap
->audio_buffer
[k
].pgo
) {
3965 SAY("ERROR: attempting to reallocate audio buffers\n");
3967 pbuf
= (void *) __get_free_page(GFP_KERNEL
);
3968 if ((void *)NULL
== pbuf
) {
3969 SAY("ERROR: Could not allocate audio " \
3970 "buffer page %i\n", k
);
3973 peasycap
->allocation_audio_page
+= 1;
3975 peasycap
->audio_buffer
[k
].pgo
= pbuf
;
3977 peasycap
->audio_buffer
[k
].pto
= peasycap
->audio_buffer
[k
].pgo
;
3980 peasycap
->audio_fill
= 0;
3981 peasycap
->audio_read
= 0;
3982 JOT(4, "allocation of audio buffer done: %i pages\n", k
);
3983 /*---------------------------------------------------------------------------*/
3984 JOT(4, "allocating %i isoc audio buffers of size %i\n", \
3985 AUDIO_ISOC_BUFFER_MANY
, peasycap
->audio_isoc_buffer_size
);
3986 JOT(4, ".... each occupying contiguous memory pages\n");
3988 for (k
= 0; k
< AUDIO_ISOC_BUFFER_MANY
; k
++) {
3989 pbuf
= (void *)__get_free_pages(GFP_KERNEL
, AUDIO_ISOC_ORDER
);
3991 SAY("ERROR: Could not allocate isoc audio buffer " \
3995 peasycap
->allocation_audio_page
+= \
3996 ((unsigned int)(0x01 << AUDIO_ISOC_ORDER
));
3998 peasycap
->audio_isoc_buffer
[k
].pgo
= pbuf
;
3999 peasycap
->audio_isoc_buffer
[k
].pto
= pbuf
+ \
4000 peasycap
->audio_isoc_buffer_size
;
4001 peasycap
->audio_isoc_buffer
[k
].kount
= k
;
4003 JOT(4, "allocation of isoc audio buffers done.\n");
4004 /*---------------------------------------------------------------------------*/
4006 * ALLOCATE AND INITIALIZE MULTIPLE struct urb ...
4008 /*---------------------------------------------------------------------------*/
4009 JOT(4, "allocating %i struct urb.\n", AUDIO_ISOC_BUFFER_MANY
);
4010 JOT(4, "using %i=peasycap->audio_isoc_framesperdesc\n", \
4011 peasycap
->audio_isoc_framesperdesc
);
4012 JOT(4, "using %i=peasycap->audio_isoc_maxframesize\n", \
4013 peasycap
->audio_isoc_maxframesize
);
4014 JOT(4, "using %i=peasycap->audio_isoc_buffer_size\n", \
4015 peasycap
->audio_isoc_buffer_size
);
4017 for (k
= 0; k
< AUDIO_ISOC_BUFFER_MANY
; k
++) {
4018 purb
= usb_alloc_urb(peasycap
->audio_isoc_framesperdesc
, \
4021 SAY("ERROR: usb_alloc_urb returned NULL for buffer " \
4025 peasycap
->allocation_audio_urb
+= 1 ;
4026 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
4027 pdata_urb
= kzalloc(sizeof(struct data_urb
), GFP_KERNEL
);
4028 if (NULL
== pdata_urb
) {
4029 SAY("ERROR: Could not allocate struct data_urb.\n");
4032 peasycap
->allocation_audio_struct
+= \
4033 sizeof(struct data_urb
);
4035 pdata_urb
->purb
= purb
;
4036 pdata_urb
->isbuf
= k
;
4037 pdata_urb
->length
= 0;
4038 list_add_tail(&(pdata_urb
->list_head
), \
4039 peasycap
->purb_audio_head
);
4040 /*---------------------------------------------------------------------------*/
4042 * ... AND INITIALIZE THEM
4044 /*---------------------------------------------------------------------------*/
4046 JOT(4, "initializing audio urbs thus:\n");
4047 JOT(4, " purb->interval = 1;\n");
4048 JOT(4, " purb->dev = peasycap->pusb_device;\n");
4049 JOT(4, " purb->pipe = usb_rcvisocpipe(peasycap->" \
4050 "pusb_device,%i);\n", \
4051 peasycap
->audio_endpointnumber
);
4052 JOT(4, " purb->transfer_flags = URB_ISO_ASAP;\n");
4053 JOT(4, " purb->transfer_buffer = " \
4054 "peasycap->audio_isoc_buffer[.].pgo;\n");
4055 JOT(4, " purb->transfer_buffer_length = %i;\n", \
4056 peasycap
->audio_isoc_buffer_size
);
4057 JOT(4, " purb->complete = easysnd_complete;\n");
4058 JOT(4, " purb->context = peasycap;\n");
4059 JOT(4, " purb->start_frame = 0;\n");
4060 JOT(4, " purb->number_of_packets = %i;\n", \
4061 peasycap
->audio_isoc_framesperdesc
);
4062 JOT(4, " for (j = 0; j < %i; j++)\n", \
4063 peasycap
->audio_isoc_framesperdesc
);
4065 JOT(4, " purb->iso_frame_desc[j].offset = j*%i;\n",\
4066 peasycap
->audio_isoc_maxframesize
);
4067 JOT(4, " purb->iso_frame_desc[j].length = %i;\n", \
4068 peasycap
->audio_isoc_maxframesize
);
4073 purb
->dev
= peasycap
->pusb_device
;
4074 purb
->pipe
= usb_rcvisocpipe(peasycap
->pusb_device
, \
4075 peasycap
->audio_endpointnumber
);
4076 purb
->transfer_flags
= URB_ISO_ASAP
;
4077 purb
->transfer_buffer
= peasycap
->audio_isoc_buffer
[k
].pgo
;
4078 purb
->transfer_buffer_length
= \
4079 peasycap
->audio_isoc_buffer_size
;
4080 purb
->complete
= easysnd_complete
;
4081 purb
->context
= peasycap
;
4082 purb
->start_frame
= 0;
4083 purb
->number_of_packets
= peasycap
->audio_isoc_framesperdesc
;
4084 for (j
= 0; j
< peasycap
->audio_isoc_framesperdesc
; j
++) {
4085 purb
->iso_frame_desc
[j
].offset
= j
* \
4086 peasycap
->audio_isoc_maxframesize
;
4087 purb
->iso_frame_desc
[j
].length
= \
4088 peasycap
->audio_isoc_maxframesize
;
4091 JOT(4, "allocation of %i struct urb done.\n", k
);
4092 /*---------------------------------------------------------------------------*/
4094 * SAVE POINTER peasycap IN THIS INTERFACE.
4096 /*---------------------------------------------------------------------------*/
4097 usb_set_intfdata(pusb_interface
, peasycap
);
4098 /*---------------------------------------------------------------------------*/
4100 * THE AUDIO DEVICE CAN BE REGISTERED NOW, AS IT IS READY.
4102 /*---------------------------------------------------------------------------*/
4103 rc
= usb_register_dev(pusb_interface
, &easysnd_class
);
4105 err("Not able to get a minor for this device.");
4106 usb_set_intfdata(pusb_interface
, NULL
);
4109 (peasycap
->registered_audio
)++;
4110 /*---------------------------------------------------------------------------*/
4112 * LET THE USER KNOW WHAT NODE THE AUDIO DEVICE IS ATTACHED TO.
4114 /*---------------------------------------------------------------------------*/
4115 SAY("easysnd attached to minor #%d\n", pusb_interface
->minor
);
4118 /*---------------------------------------------------------------------------*/
4120 * INTERFACES OTHER THAN 0, 1 AND 2 ARE UNEXPECTED
4122 /*---------------------------------------------------------------------------*/
4124 JOT(4, "ERROR: unexpected interface %i\n", bInterfaceNumber
);
4128 JOT(4, "ends successfully for interface %i\n", \
4129 pusb_interface_descriptor
->bInterfaceNumber
);
4132 /*****************************************************************************/
4133 /*---------------------------------------------------------------------------*/
4135 * WHEN THIS FUNCTION IS CALLED THE DEVICE HAS ALREADY BEEN PHYSICALLY
4137 * HENCE peasycap->pusb_device IS NO LONGER VALID AND MUST BE SET TO NULL.
4139 /*---------------------------------------------------------------------------*/
4141 easycap_usb_disconnect(struct usb_interface
*pusb_interface
)
4143 struct usb_host_interface
*pusb_host_interface
;
4144 struct usb_interface_descriptor
*pusb_interface_descriptor
;
4145 __u8 bInterfaceNumber
;
4146 struct easycap
*peasycap
;
4148 struct list_head
*plist_head
;
4149 struct data_urb
*pdata_urb
;
4154 if ((struct usb_interface
*)NULL
== pusb_interface
) {
4155 JOT(4, "ERROR: pusb_interface is NULL\n");
4158 pusb_host_interface
= pusb_interface
->cur_altsetting
;
4159 if ((struct usb_host_interface
*)NULL
== pusb_host_interface
) {
4160 JOT(4, "ERROR: pusb_host_interface is NULL\n");
4163 pusb_interface_descriptor
= &(pusb_host_interface
->desc
);
4164 if ((struct usb_interface_descriptor
*)NULL
== pusb_interface_descriptor
) {
4165 JOT(4, "ERROR: pusb_interface_descriptor is NULL\n");
4168 bInterfaceNumber
= pusb_interface_descriptor
->bInterfaceNumber
;
4169 minor
= pusb_interface
->minor
;
4170 JOT(4, "intf[%i]: minor=%i\n", bInterfaceNumber
, minor
);
4172 peasycap
= usb_get_intfdata(pusb_interface
);
4173 if ((struct easycap
*)NULL
== peasycap
)
4174 SAY("ERROR: peasycap is NULL\n");
4176 peasycap
->pusb_device
= (struct usb_device
*)NULL
;
4177 switch (bInterfaceNumber
) {
4178 /*---------------------------------------------------------------------------*/
4180 if ((struct list_head
*)NULL
!= peasycap
->purb_video_head
) {
4181 JOT(4, "killing video urbs\n");
4183 list_for_each(plist_head
, (peasycap
->purb_video_head
))
4185 pdata_urb
= list_entry(plist_head
, \
4186 struct data_urb
, list_head
);
4187 if ((struct data_urb
*)NULL
!= pdata_urb
) {
4188 if ((struct urb
*)NULL
!= \
4190 usb_kill_urb(pdata_urb
->purb
);
4195 JOT(4, "%i video urbs killed\n", m
);
4197 SAY("ERROR: peasycap->purb_video_head is NULL\n");
4200 /*---------------------------------------------------------------------------*/
4202 if ((struct list_head
*)NULL
!= peasycap
->purb_audio_head
) {
4203 JOT(4, "killing audio urbs\n");
4205 list_for_each(plist_head
, \
4206 (peasycap
->purb_audio_head
)) {
4207 pdata_urb
= list_entry(plist_head
, \
4208 struct data_urb
, list_head
);
4209 if ((struct data_urb
*)NULL
!= pdata_urb
) {
4210 if ((struct urb
*)NULL
!= \
4212 usb_kill_urb(pdata_urb
->purb
);
4217 JOT(4, "%i audio urbs killed\n", m
);
4219 SAY("ERROR: peasycap->purb_audio_head is NULL\n");
4222 /*---------------------------------------------------------------------------*/
4227 /*--------------------------------------------------------------------------*/
4231 /*--------------------------------------------------------------------------*/
4232 switch (bInterfaceNumber
) {
4234 #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
4235 if ((struct easycap
*)NULL
== peasycap
) {
4236 SAY("ERROR: peasycap has become NULL\n");
4239 usb_deregister_dev(pusb_interface
, &easycap_class
);
4240 (peasycap
->registered_video
)--;
4242 JOT(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber
);
4244 SAY("easycap detached from minor #%d\n", minor
);
4246 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
4248 if ((struct easycap
*)NULL
== peasycap
)
4249 SAY("ERROR: peasycap has become NULL\n");
4252 video_unregister_device(peasycap
->pvideo_device
);
4253 (peasycap
->registered_video
)--;
4255 JOT(4, "unregistered with videodev: %i=minor\n", \
4256 pvideo_device
->minor
);
4258 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
4259 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
4265 usb_deregister_dev(pusb_interface
, &easysnd_class
);
4266 if ((struct easycap
*)NULL
!= peasycap
)
4267 (peasycap
->registered_audio
)--;
4269 JOT(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber
);
4272 SAY("easysnd detached from minor #%d\n", minor
);
4278 /*---------------------------------------------------------------------------*/
4280 * CALL easycap_delete() IF NO REMAINING REFERENCES TO peasycap
4282 /*---------------------------------------------------------------------------*/
4283 if ((struct easycap
*)NULL
== peasycap
) {
4284 SAY("ERROR: peasycap has become NULL\n");
4285 SAY("cannot call kref_put()\n");
4286 SAY("ending unsuccessfully: may cause memory leak\n");
4289 if (!peasycap
->kref
.refcount
.counter
) {
4290 SAY("ERROR: peasycap->kref.refcount.counter is zero " \
4291 "so cannot call kref_put()\n");
4292 SAY("ending unsuccessfully: may cause memory leak\n");
4295 JOT(4, "intf[%i]: kref_put() with %i=peasycap->kref.refcount.counter\n", \
4296 bInterfaceNumber
, (int)peasycap
->kref
.refcount
.counter
);
4297 kref_put(&peasycap
->kref
, easycap_delete
);
4298 JOT(4, "intf[%i]: kref_put() done.\n", bInterfaceNumber
);
4299 /*---------------------------------------------------------------------------*/
4304 /*****************************************************************************/
4306 easycap_module_init(void)
4310 SAY("========easycap=======\n");
4311 JOT(4, "begins. %i=debug\n", easycap_debug
);
4312 SAY("version: " EASYCAP_DRIVER_VERSION
"\n");
4313 /*---------------------------------------------------------------------------*/
4315 * REGISTER THIS DRIVER WITH THE USB SUBSYTEM.
4317 /*---------------------------------------------------------------------------*/
4318 JOT(4, "registering driver easycap\n");
4320 result
= usb_register(&easycap_usb_driver
);
4322 SAY("ERROR: usb_register returned %i\n", result
);
4327 /*****************************************************************************/
4329 easycap_module_exit(void)
4333 /*---------------------------------------------------------------------------*/
4335 * DEREGISTER THIS DRIVER WITH THE USB SUBSYTEM.
4337 /*---------------------------------------------------------------------------*/
4338 usb_deregister(&easycap_usb_driver
);
4342 /*****************************************************************************/
4344 module_init(easycap_module_init
);
4345 module_exit(easycap_module_exit
);
4347 MODULE_LICENSE("GPL");
4348 MODULE_AUTHOR("R.M. Thomas <rmthomas@sciolus.org>");
4349 MODULE_DESCRIPTION(EASYCAP_DRIVER_DESCRIPTION
);
4350 MODULE_VERSION(EASYCAP_DRIVER_VERSION
);
4351 #if defined(EASYCAP_DEBUG)
4352 MODULE_PARM_DESC(easycap_debug
, "debug: 0 (default), 1, 2,...");
4353 #endif /*EASYCAP_DEBUG*/
4354 /*****************************************************************************/