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 .unlocked_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 .unlocked_ioctl
= easycap_ioctl
,
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 .unlocked_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 /*---------------------------------------------------------------------------*/
2975 /*---------------------------------------------------------------------------*/
2977 easycap_usb_probe(struct usb_interface
*pusb_interface
, \
2978 const struct usb_device_id
*id
)
2980 struct usb_device
*pusb_device
, *pusb_device1
;
2981 struct usb_host_interface
*pusb_host_interface
;
2982 struct usb_endpoint_descriptor
*pepd
;
2983 struct usb_interface_descriptor
*pusb_interface_descriptor
;
2984 struct usb_interface_assoc_descriptor
*pusb_interface_assoc_descriptor
;
2986 static struct easycap
*peasycap
/*=NULL*/;
2987 struct data_urb
*pdata_urb
;
2988 size_t wMaxPacketSize
;
2989 int ISOCwMaxPacketSize
;
2990 int BULKwMaxPacketSize
;
2991 int INTwMaxPacketSize
;
2992 int CTRLwMaxPacketSize
;
2993 __u8 bEndpointAddress
;
2994 __u8 ISOCbEndpointAddress
;
2995 __u8 INTbEndpointAddress
;
2996 int isin
, i
, j
, k
, m
;
2997 __u8 bInterfaceNumber
;
2998 __u8 bInterfaceClass
;
2999 __u8 bInterfaceSubClass
;
3001 int okalt
[8], isokalt
;
3002 int okepn
[8], isokepn
;
3003 int okmps
[8], isokmps
;
3009 if ((struct usb_interface
*)NULL
== pusb_interface
) {
3010 SAY("ERROR: pusb_interface is NULL\n");
3013 /*---------------------------------------------------------------------------*/
3015 * GET POINTER TO STRUCTURE usb_device
3017 /*---------------------------------------------------------------------------*/
3018 pusb_device1
= container_of(pusb_interface
->dev
.parent
, \
3019 struct usb_device
, dev
);
3020 if ((struct usb_device
*)NULL
== pusb_device1
) {
3021 SAY("ERROR: pusb_device1 is NULL\n");
3024 pusb_device
= usb_get_dev(pusb_device1
);
3025 if ((struct usb_device
*)NULL
== pusb_device
) {
3026 SAY("ERROR: pusb_device is NULL\n");
3029 if ((unsigned long int)pusb_device1
!= (unsigned long int)pusb_device
) {
3030 JOT(4, "ERROR: pusb_device1 != pusb_device\n");
3034 JOT(4, "bNumConfigurations=%i\n", pusb_device
->descriptor
.bNumConfigurations
);
3036 /*---------------------------------------------------------------------------*/
3037 pusb_host_interface
= pusb_interface
->cur_altsetting
;
3038 if (NULL
== pusb_host_interface
) {
3039 SAY("ERROR: pusb_host_interface is NULL\n");
3042 pusb_interface_descriptor
= &(pusb_host_interface
->desc
);
3043 if (NULL
== pusb_interface_descriptor
) {
3044 SAY("ERROR: pusb_interface_descriptor is NULL\n");
3047 /*---------------------------------------------------------------------------*/
3049 * GET PROPERTIES OF PROBED INTERFACE
3051 /*---------------------------------------------------------------------------*/
3052 bInterfaceNumber
= pusb_interface_descriptor
->bInterfaceNumber
;
3053 bInterfaceClass
= pusb_interface_descriptor
->bInterfaceClass
;
3054 bInterfaceSubClass
= pusb_interface_descriptor
->bInterfaceSubClass
;
3056 JOT(4, "intf[%i]: pusb_interface->num_altsetting=%i\n", \
3057 bInterfaceNumber
, pusb_interface
->num_altsetting
);
3058 JOT(4, "intf[%i]: pusb_interface->cur_altsetting - " \
3059 "pusb_interface->altsetting=%li\n", bInterfaceNumber
, \
3060 (long int)(pusb_interface
->cur_altsetting
- \
3061 pusb_interface
->altsetting
));
3062 switch (bInterfaceClass
) {
3063 case USB_CLASS_AUDIO
: {
3064 JOT(4, "intf[%i]: bInterfaceClass=0x%02X=USB_CLASS_AUDIO\n", \
3065 bInterfaceNumber
, bInterfaceClass
); break;
3067 case USB_CLASS_VIDEO
: {
3068 JOT(4, "intf[%i]: bInterfaceClass=0x%02X=USB_CLASS_VIDEO\n", \
3069 bInterfaceNumber
, bInterfaceClass
); break;
3071 case USB_CLASS_VENDOR_SPEC
: {
3072 JOT(4, "intf[%i]: bInterfaceClass=0x%02X=USB_CLASS_VENDOR_SPEC\n", \
3073 bInterfaceNumber
, bInterfaceClass
); break;
3078 switch (bInterfaceSubClass
) {
3080 JOT(4, "intf[%i]: bInterfaceSubClass=0x%02X=AUDIOCONTROL\n", \
3081 bInterfaceNumber
, bInterfaceSubClass
); break;
3084 JOT(4, "intf[%i]: bInterfaceSubClass=0x%02X=AUDIOSTREAMING\n", \
3085 bInterfaceNumber
, bInterfaceSubClass
); break;
3088 JOT(4, "intf[%i]: bInterfaceSubClass=0x%02X=MIDISTREAMING\n", \
3089 bInterfaceNumber
, bInterfaceSubClass
); break;
3094 /*---------------------------------------------------------------------------*/
3095 pusb_interface_assoc_descriptor
= pusb_interface
->intf_assoc
;
3096 if (NULL
!= pusb_interface_assoc_descriptor
) {
3097 JOT(4, "intf[%i]: bFirstInterface=0x%02X bInterfaceCount=0x%02X\n", \
3099 pusb_interface_assoc_descriptor
->bFirstInterface
, \
3100 pusb_interface_assoc_descriptor
->bInterfaceCount
);
3102 JOT(4, "intf[%i]: pusb_interface_assoc_descriptor is NULL\n", \
3105 /*---------------------------------------------------------------------------*/
3107 * A NEW struct easycap IS ALWAYS ALLOCATED WHEN INTERFACE 0 IS PROBED.
3108 * IT IS NOT POSSIBLE HERE TO FREE ANY EXISTING struct easycap. THIS
3109 * SHOULD HAVE BEEN DONE BY easycap_delete() WHEN THE DEVICE WAS PHYSICALLY
3112 /*---------------------------------------------------------------------------*/
3113 if (0 == bInterfaceNumber
) {
3114 peasycap
= kzalloc(sizeof(struct easycap
), GFP_KERNEL
);
3115 if (NULL
== peasycap
) {
3116 SAY("ERROR: Could not allocate peasycap\n");
3119 peasycap
->allocation_video_struct
= sizeof(struct easycap
);
3120 peasycap
->allocation_video_page
= 0;
3121 peasycap
->allocation_video_urb
= 0;
3122 peasycap
->allocation_audio_struct
= 0;
3123 peasycap
->allocation_audio_page
= 0;
3124 peasycap
->allocation_audio_urb
= 0;
3126 /*---------------------------------------------------------------------------*/
3128 * INITIALIZE THE NEW easycap STRUCTURE.
3129 * NO PARAMETERS ARE SPECIFIED HERE REQUIRING THE SETTING OF REGISTERS.
3130 * THAT IS DONE FIRST BY easycap_open() AND LATER BY easycap_ioctl().
3132 /*---------------------------------------------------------------------------*/
3133 peasycap
->pusb_device
= pusb_device
;
3134 peasycap
->pusb_interface
= pusb_interface
;
3136 kref_init(&peasycap
->kref
);
3137 JOT(8, "intf[%i]: after kref_init(..._video) " \
3138 "%i=peasycap->kref.refcount.counter\n", \
3139 bInterfaceNumber
, peasycap
->kref
.refcount
.counter
);
3141 init_waitqueue_head(&(peasycap
->wq_video
));
3142 init_waitqueue_head(&(peasycap
->wq_audio
));
3144 mutex_init(&(peasycap
->mutex_timeval0
));
3145 mutex_init(&(peasycap
->mutex_timeval1
));
3147 for (k
= 0; k
< FRAME_BUFFER_MANY
; k
++)
3148 mutex_init(&(peasycap
->mutex_mmap_video
[k
]));
3151 peasycap
->microphone
= false;
3153 peasycap
->video_interface
= -1;
3154 peasycap
->video_altsetting_on
= -1;
3155 peasycap
->video_altsetting_off
= -1;
3156 peasycap
->video_endpointnumber
= -1;
3157 peasycap
->video_isoc_maxframesize
= -1;
3158 peasycap
->video_isoc_buffer_size
= -1;
3160 peasycap
->audio_interface
= -1;
3161 peasycap
->audio_altsetting_on
= -1;
3162 peasycap
->audio_altsetting_off
= -1;
3163 peasycap
->audio_endpointnumber
= -1;
3164 peasycap
->audio_isoc_maxframesize
= -1;
3165 peasycap
->audio_isoc_buffer_size
= -1;
3167 peasycap
->frame_buffer_many
= FRAME_BUFFER_MANY
;
3169 if ((struct mutex
*)NULL
== &(peasycap
->mutex_mmap_video
[0])) {
3170 SAY("ERROR: &(peasycap->mutex_mmap_video[%i]) is NULL\n", 0);
3173 /*---------------------------------------------------------------------------*/
3175 * DYNAMICALLY FILL IN THE AVAILABLE FORMATS.
3177 /*---------------------------------------------------------------------------*/
3178 rc
= fillin_formats();
3180 SAY("ERROR: fillin_formats() returned %i\n", rc
);
3183 JOT(4, "%i formats available\n", rc
);
3185 /*---------------------------------------------------------------------------*/
3186 if ((struct easycap
*)NULL
== peasycap
) {
3187 SAY("ERROR: peasycap is NULL " \
3188 "when probing interface %i\n", \
3193 JOT(8, "kref_get() with %i=peasycap->kref.refcount.counter\n", \
3194 (int)peasycap
->kref
.refcount
.counter
);
3195 kref_get(&peasycap
->kref
);
3197 /*---------------------------------------------------------------------------*/
3198 if ((USB_CLASS_VIDEO
== bInterfaceClass
) || \
3199 (USB_CLASS_VENDOR_SPEC
== bInterfaceClass
)) {
3200 if (-1 == peasycap
->video_interface
) {
3201 peasycap
->video_interface
= bInterfaceNumber
;
3202 JOT(4, "setting peasycap->video_interface=%i\n", \
3203 peasycap
->video_interface
);
3205 if (peasycap
->video_interface
!= bInterfaceNumber
) {
3206 SAY("ERROR: attempting to reset " \
3207 "peasycap->video_interface\n");
3208 SAY("...... continuing with " \
3209 "%i=peasycap->video_interface\n", \
3210 peasycap
->video_interface
);
3213 } else if ((USB_CLASS_AUDIO
== bInterfaceClass
) && \
3214 (0x02 == bInterfaceSubClass
)) {
3215 if (-1 == peasycap
->audio_interface
) {
3216 peasycap
->audio_interface
= bInterfaceNumber
;
3217 JOT(4, "setting peasycap->audio_interface=%i\n", \
3218 peasycap
->audio_interface
);
3220 if (peasycap
->audio_interface
!= bInterfaceNumber
) {
3221 SAY("ERROR: attempting to reset " \
3222 "peasycap->audio_interface\n");
3223 SAY("...... continuing with " \
3224 "%i=peasycap->audio_interface\n", \
3225 peasycap
->audio_interface
);
3229 /*---------------------------------------------------------------------------*/
3231 * INVESTIGATE ALL ALTSETTINGS.
3232 * DONE IN DETAIL BECAUSE USB DEVICE 05e1:0408 HAS DISPARATE INCARNATIONS.
3234 /*---------------------------------------------------------------------------*/
3239 for (i
= 0; i
< pusb_interface
->num_altsetting
; i
++) {
3240 pusb_host_interface
= &(pusb_interface
->altsetting
[i
]);
3241 if ((struct usb_host_interface
*)NULL
== pusb_host_interface
) {
3242 SAY("ERROR: pusb_host_interface is NULL\n");
3245 pusb_interface_descriptor
= &(pusb_host_interface
->desc
);
3246 if ((struct usb_interface_descriptor
*)NULL
== \
3247 pusb_interface_descriptor
) {
3248 SAY("ERROR: pusb_interface_descriptor is NULL\n");
3252 JOT(4, "intf[%i]alt[%i]: desc.bDescriptorType=0x%02X\n", \
3253 bInterfaceNumber
, i
, pusb_interface_descriptor
->bDescriptorType
);
3254 JOT(4, "intf[%i]alt[%i]: desc.bInterfaceNumber=0x%02X\n", \
3255 bInterfaceNumber
, i
, pusb_interface_descriptor
->bInterfaceNumber
);
3256 JOT(4, "intf[%i]alt[%i]: desc.bAlternateSetting=0x%02X\n", \
3257 bInterfaceNumber
, i
, pusb_interface_descriptor
->bAlternateSetting
);
3258 JOT(4, "intf[%i]alt[%i]: desc.bNumEndpoints=0x%02X\n", \
3259 bInterfaceNumber
, i
, pusb_interface_descriptor
->bNumEndpoints
);
3260 JOT(4, "intf[%i]alt[%i]: desc.bInterfaceClass=0x%02X\n", \
3261 bInterfaceNumber
, i
, pusb_interface_descriptor
->bInterfaceClass
);
3262 JOT(4, "intf[%i]alt[%i]: desc.bInterfaceSubClass=0x%02X\n", \
3263 bInterfaceNumber
, i
, pusb_interface_descriptor
->bInterfaceSubClass
);
3264 JOT(4, "intf[%i]alt[%i]: desc.bInterfaceProtocol=0x%02X\n", \
3265 bInterfaceNumber
, i
, pusb_interface_descriptor
->bInterfaceProtocol
);
3266 JOT(4, "intf[%i]alt[%i]: desc.iInterface=0x%02X\n", \
3267 bInterfaceNumber
, i
, pusb_interface_descriptor
->iInterface
);
3269 ISOCwMaxPacketSize
= -1;
3270 BULKwMaxPacketSize
= -1;
3271 INTwMaxPacketSize
= -1;
3272 CTRLwMaxPacketSize
= -1;
3273 ISOCbEndpointAddress
= 0;
3274 INTbEndpointAddress
= 0;
3276 if (0 == pusb_interface_descriptor
->bNumEndpoints
)
3277 JOT(4, "intf[%i]alt[%i] has no endpoints\n", \
3278 bInterfaceNumber
, i
);
3279 /*---------------------------------------------------------------------------*/
3280 for (j
= 0; j
< pusb_interface_descriptor
->bNumEndpoints
; j
++) {
3281 pepd
= &(pusb_host_interface
->endpoint
[j
].desc
);
3282 if ((struct usb_endpoint_descriptor
*)NULL
== pepd
) {
3283 SAY("ERROR: pepd is NULL.\n");
3284 SAY("...... skipping\n");
3287 wMaxPacketSize
= le16_to_cpu(pepd
->wMaxPacketSize
);
3288 bEndpointAddress
= pepd
->bEndpointAddress
;
3290 JOT(4, "intf[%i]alt[%i]end[%i]: bEndpointAddress=0x%X\n", \
3291 bInterfaceNumber
, i
, j
, \
3292 pepd
->bEndpointAddress
);
3293 JOT(4, "intf[%i]alt[%i]end[%i]: bmAttributes=0x%X\n", \
3294 bInterfaceNumber
, i
, j
, \
3295 pepd
->bmAttributes
);
3296 JOT(4, "intf[%i]alt[%i]end[%i]: wMaxPacketSize=%i\n", \
3297 bInterfaceNumber
, i
, j
, \
3298 pepd
->wMaxPacketSize
);
3299 JOT(4, "intf[%i]alt[%i]end[%i]: bInterval=%i\n",
3300 bInterfaceNumber
, i
, j
, \
3303 if (pepd
->bEndpointAddress
& USB_DIR_IN
) {
3304 JOT(4, "intf[%i]alt[%i]end[%i] is an IN endpoint\n",\
3305 bInterfaceNumber
, i
, j
);
3308 JOT(4, "intf[%i]alt[%i]end[%i] is an OUT endpoint\n",\
3309 bInterfaceNumber
, i
, j
);
3310 SAY("ERROR: OUT endpoint unexpected\n");
3311 SAY("...... continuing\n");
3314 if ((pepd
->bmAttributes
& \
3315 USB_ENDPOINT_XFERTYPE_MASK
) == \
3316 USB_ENDPOINT_XFER_ISOC
) {
3317 JOT(4, "intf[%i]alt[%i]end[%i] is an ISOC endpoint\n",\
3318 bInterfaceNumber
, i
, j
);
3320 switch (bInterfaceClass
) {
3321 case USB_CLASS_VIDEO
:
3322 case USB_CLASS_VENDOR_SPEC
: {
3325 "peasycap is NULL\n");
3328 if (pepd
->wMaxPacketSize
) {
3340 bEndpointAddress
& \
3359 if (-1 == peasycap
->\
3360 video_altsetting_off
) {
3362 video_altsetting_off
=\
3364 JOT(4, "%i=video_" \
3368 video_altsetting_off
);
3370 SAY("ERROR: peasycap" \
3371 "->video_altsetting_" \
3372 "off already set\n");
3374 "continuing with " \
3375 "%i=peasycap->video_" \
3376 "altsetting_off\n", \
3378 video_altsetting_off
);
3383 case USB_CLASS_AUDIO
: {
3384 if (0x02 != bInterfaceSubClass
)
3388 "peasycap is NULL\n");
3391 if (pepd
->wMaxPacketSize
) {
3393 okalt
[isokalt
] = i
;
3403 bEndpointAddress
& \
3422 if (-1 == peasycap
->\
3423 audio_altsetting_off
) {
3425 audio_altsetting_off
=\
3427 JOT(4, "%i=audio_" \
3431 audio_altsetting_off
);
3433 SAY("ERROR: peasycap" \
3434 "->audio_altsetting_" \
3435 "off already set\n");
3437 "continuing with " \
3439 audio_altsetting_" \
3442 audio_altsetting_off
);
3451 } else if ((pepd
->bmAttributes
& \
3452 USB_ENDPOINT_XFERTYPE_MASK
) ==\
3453 USB_ENDPOINT_XFER_BULK
) {
3454 JOT(4, "intf[%i]alt[%i]end[%i] is a BULK endpoint\n",\
3455 bInterfaceNumber
, i
, j
);
3456 } else if ((pepd
->bmAttributes
& \
3457 USB_ENDPOINT_XFERTYPE_MASK
) ==\
3458 USB_ENDPOINT_XFER_INT
) {
3459 JOT(4, "intf[%i]alt[%i]end[%i] is an INT endpoint\n",\
3460 bInterfaceNumber
, i
, j
);
3462 JOT(4, "intf[%i]alt[%i]end[%i] is a CTRL endpoint\n",\
3463 bInterfaceNumber
, i
, j
);
3465 if (0 == pepd
->wMaxPacketSize
) {
3466 JOT(4, "intf[%i]alt[%i]end[%i] " \
3467 "has zero packet size\n", \
3468 bInterfaceNumber
, i
, j
);
3472 /*---------------------------------------------------------------------------*/
3474 * PERFORM INITIALIZATION OF THE PROBED INTERFACE
3476 /*---------------------------------------------------------------------------*/
3477 JOT(4, "initialization begins for interface %i\n", \
3478 pusb_interface_descriptor
->bInterfaceNumber
);
3479 switch (bInterfaceNumber
) {
3480 /*---------------------------------------------------------------------------*/
3482 * INTERFACE 0 IS THE VIDEO INTERFACE
3484 /*---------------------------------------------------------------------------*/
3487 SAY("MISTAKE: peasycap is NULL\n");
3491 SAY("ERROR: no viable video_altsetting_on\n");
3494 peasycap
->video_altsetting_on
= okalt
[isokalt
- 1];
3495 JOT(4, "%i=video_altsetting_on <====\n", \
3496 peasycap
->video_altsetting_on
);
3499 SAY("ERROR: no viable video_endpointnumber\n");
3502 peasycap
->video_endpointnumber
= okepn
[isokepn
- 1];
3503 JOT(4, "%i=video_endpointnumber\n", \
3504 peasycap
->video_endpointnumber
);
3507 SAY("ERROR: no viable video_maxpacketsize\n");
3509 /*---------------------------------------------------------------------------*/
3511 * DECIDE THE VIDEO STREAMING PARAMETERS
3513 /*---------------------------------------------------------------------------*/
3515 maxpacketsize
= okmps
[isokmps
- 1] - 1024;
3516 if (USB_2_0_MAXPACKETSIZE
> maxpacketsize
) {
3517 peasycap
->video_isoc_maxframesize
= maxpacketsize
;
3519 peasycap
->video_isoc_maxframesize
= \
3520 USB_2_0_MAXPACKETSIZE
;
3522 JOT(4, "%i=video_isoc_maxframesize\n", \
3523 peasycap
->video_isoc_maxframesize
);
3524 if (0 >= peasycap
->video_isoc_maxframesize
) {
3525 SAY("ERROR: bad video_isoc_maxframesize\n");
3528 peasycap
->video_isoc_framesperdesc
= VIDEO_ISOC_FRAMESPERDESC
;
3529 JOT(4, "%i=video_isoc_framesperdesc\n", \
3530 peasycap
->video_isoc_framesperdesc
);
3531 if (0 >= peasycap
->video_isoc_framesperdesc
) {
3532 SAY("ERROR: bad video_isoc_framesperdesc\n");
3535 peasycap
->video_isoc_buffer_size
= \
3536 peasycap
->video_isoc_maxframesize
* \
3537 peasycap
->video_isoc_framesperdesc
;
3538 JOT(4, "%i=video_isoc_buffer_size\n", \
3539 peasycap
->video_isoc_buffer_size
);
3540 if ((PAGE_SIZE
<< VIDEO_ISOC_ORDER
) < \
3541 peasycap
->video_isoc_buffer_size
) {
3543 "peasycap->video_isoc_buffer_size too big\n");
3547 /*---------------------------------------------------------------------------*/
3548 if (-1 == peasycap
->video_interface
) {
3549 SAY("MISTAKE: video_interface is unset\n");
3552 if (-1 == peasycap
->video_altsetting_on
) {
3553 SAY("MISTAKE: video_altsetting_on is unset\n");
3556 if (-1 == peasycap
->video_altsetting_off
) {
3557 SAY("MISTAKE: video_interface_off is unset\n");
3560 if (-1 == peasycap
->video_endpointnumber
) {
3561 SAY("MISTAKE: video_endpointnumber is unset\n");
3564 if (-1 == peasycap
->video_isoc_maxframesize
) {
3565 SAY("MISTAKE: video_isoc_maxframesize is unset\n");
3568 if (-1 == peasycap
->video_isoc_buffer_size
) {
3569 SAY("MISTAKE: video_isoc_buffer_size is unset\n");
3572 /*---------------------------------------------------------------------------*/
3574 * ALLOCATE MEMORY FOR VIDEO BUFFERS. LISTS MUST BE INITIALIZED FIRST.
3576 /*---------------------------------------------------------------------------*/
3577 INIT_LIST_HEAD(&(peasycap
->urb_video_head
));
3578 peasycap
->purb_video_head
= &(peasycap
->urb_video_head
);
3579 /*---------------------------------------------------------------------------*/
3580 JOT(4, "allocating %i frame buffers of size %li\n", \
3581 FRAME_BUFFER_MANY
, (long int)FRAME_BUFFER_SIZE
);
3582 JOT(4, ".... each scattered over %li pages\n", \
3583 FRAME_BUFFER_SIZE
/PAGE_SIZE
);
3585 for (k
= 0; k
< FRAME_BUFFER_MANY
; k
++) {
3586 for (m
= 0; m
< FRAME_BUFFER_SIZE
/PAGE_SIZE
; m
++) {
3587 if ((void *)NULL
!= peasycap
->frame_buffer
[k
][m
].pgo
)
3588 SAY("attempting to reallocate frame " \
3591 pbuf
= (void *)__get_free_page(GFP_KERNEL
);
3592 if ((void *)NULL
== pbuf
) {
3593 SAY("ERROR: Could not allocate frame "\
3594 "buffer %i page %i\n", k
, m
);
3597 peasycap
->allocation_video_page
+= 1;
3598 peasycap
->frame_buffer
[k
][m
].pgo
= pbuf
;
3600 peasycap
->frame_buffer
[k
][m
].pto
= \
3601 peasycap
->frame_buffer
[k
][m
].pgo
;
3605 peasycap
->frame_fill
= 0;
3606 peasycap
->frame_read
= 0;
3607 JOT(4, "allocation of frame buffers done: %i pages\n", k
* \
3609 /*---------------------------------------------------------------------------*/
3610 JOT(4, "allocating %i field buffers of size %li\n", \
3611 FIELD_BUFFER_MANY
, (long int)FIELD_BUFFER_SIZE
);
3612 JOT(4, ".... each scattered over %li pages\n", \
3613 FIELD_BUFFER_SIZE
/PAGE_SIZE
);
3615 for (k
= 0; k
< FIELD_BUFFER_MANY
; k
++) {
3616 for (m
= 0; m
< FIELD_BUFFER_SIZE
/PAGE_SIZE
; m
++) {
3617 if ((void *)NULL
!= peasycap
->field_buffer
[k
][m
].pgo
) {
3618 SAY("ERROR: attempting to reallocate " \
3621 pbuf
= (void *) __get_free_page(GFP_KERNEL
);
3622 if ((void *)NULL
== pbuf
) {
3623 SAY("ERROR: Could not allocate field" \
3624 " buffer %i page %i\n", k
, m
);
3628 peasycap
->allocation_video_page
+= 1;
3629 peasycap
->field_buffer
[k
][m
].pgo
= pbuf
;
3631 peasycap
->field_buffer
[k
][m
].pto
= \
3632 peasycap
->field_buffer
[k
][m
].pgo
;
3634 peasycap
->field_buffer
[k
][0].kount
= 0x0200;
3636 peasycap
->field_fill
= 0;
3637 peasycap
->field_page
= 0;
3638 peasycap
->field_read
= 0;
3639 JOT(4, "allocation of field buffers done: %i pages\n", k
* \
3641 /*---------------------------------------------------------------------------*/
3642 JOT(4, "allocating %i isoc video buffers of size %i\n", \
3643 VIDEO_ISOC_BUFFER_MANY
, \
3644 peasycap
->video_isoc_buffer_size
);
3645 JOT(4, ".... each occupying contiguous memory pages\n");
3647 for (k
= 0; k
< VIDEO_ISOC_BUFFER_MANY
; k
++) {
3648 pbuf
= (void *)__get_free_pages(GFP_KERNEL
, VIDEO_ISOC_ORDER
);
3650 SAY("ERROR: Could not allocate isoc video buffer " \
3654 peasycap
->allocation_video_page
+= \
3655 ((unsigned int)(0x01 << VIDEO_ISOC_ORDER
));
3657 peasycap
->video_isoc_buffer
[k
].pgo
= pbuf
;
3658 peasycap
->video_isoc_buffer
[k
].pto
= pbuf
+ \
3659 peasycap
->video_isoc_buffer_size
;
3660 peasycap
->video_isoc_buffer
[k
].kount
= k
;
3662 JOT(4, "allocation of isoc video buffers done: %i pages\n", \
3663 k
* (0x01 << VIDEO_ISOC_ORDER
));
3664 /*---------------------------------------------------------------------------*/
3666 * ALLOCATE AND INITIALIZE MULTIPLE struct urb ...
3668 /*---------------------------------------------------------------------------*/
3669 JOT(4, "allocating %i struct urb.\n", VIDEO_ISOC_BUFFER_MANY
);
3670 JOT(4, "using %i=peasycap->video_isoc_framesperdesc\n", \
3671 peasycap
->video_isoc_framesperdesc
);
3672 JOT(4, "using %i=peasycap->video_isoc_maxframesize\n", \
3673 peasycap
->video_isoc_maxframesize
);
3674 JOT(4, "using %i=peasycap->video_isoc_buffer_sizen", \
3675 peasycap
->video_isoc_buffer_size
);
3677 for (k
= 0; k
< VIDEO_ISOC_BUFFER_MANY
; k
++) {
3678 purb
= usb_alloc_urb(peasycap
->video_isoc_framesperdesc
, \
3681 SAY("ERROR: usb_alloc_urb returned NULL for buffer " \
3685 peasycap
->allocation_video_urb
+= 1;
3686 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
3687 pdata_urb
= kzalloc(sizeof(struct data_urb
), GFP_KERNEL
);
3688 if (NULL
== pdata_urb
) {
3689 SAY("ERROR: Could not allocate struct data_urb.\n");
3692 peasycap
->allocation_video_struct
+= \
3693 sizeof(struct data_urb
);
3695 pdata_urb
->purb
= purb
;
3696 pdata_urb
->isbuf
= k
;
3697 pdata_urb
->length
= 0;
3698 list_add_tail(&(pdata_urb
->list_head
), \
3699 peasycap
->purb_video_head
);
3700 /*---------------------------------------------------------------------------*/
3702 * ... AND INITIALIZE THEM
3704 /*---------------------------------------------------------------------------*/
3706 JOT(4, "initializing video urbs thus:\n");
3707 JOT(4, " purb->interval = 1;\n");
3708 JOT(4, " purb->dev = peasycap->pusb_device;\n");
3709 JOT(4, " purb->pipe = usb_rcvisocpipe" \
3710 "(peasycap->pusb_device,%i);\n", \
3711 peasycap
->video_endpointnumber
);
3712 JOT(4, " purb->transfer_flags = URB_ISO_ASAP;\n");
3713 JOT(4, " purb->transfer_buffer = peasycap->" \
3714 "video_isoc_buffer[.].pgo;\n");
3715 JOT(4, " purb->transfer_buffer_length = %i;\n", \
3716 peasycap
->video_isoc_buffer_size
);
3717 JOT(4, " purb->complete = easycap_complete;\n");
3718 JOT(4, " purb->context = peasycap;\n");
3719 JOT(4, " purb->start_frame = 0;\n");
3720 JOT(4, " purb->number_of_packets = %i;\n", \
3721 peasycap
->video_isoc_framesperdesc
);
3722 JOT(4, " for (j = 0; j < %i; j++)\n", \
3723 peasycap
->video_isoc_framesperdesc
);
3725 JOT(4, " purb->iso_frame_desc[j].offset = j*%i;\n",\
3726 peasycap
->video_isoc_maxframesize
);
3727 JOT(4, " purb->iso_frame_desc[j].length = %i;\n", \
3728 peasycap
->video_isoc_maxframesize
);
3733 purb
->dev
= peasycap
->pusb_device
;
3734 purb
->pipe
= usb_rcvisocpipe(peasycap
->pusb_device
, \
3735 peasycap
->video_endpointnumber
);
3736 purb
->transfer_flags
= URB_ISO_ASAP
;
3737 purb
->transfer_buffer
= peasycap
->video_isoc_buffer
[k
].pgo
;
3738 purb
->transfer_buffer_length
= \
3739 peasycap
->video_isoc_buffer_size
;
3740 purb
->complete
= easycap_complete
;
3741 purb
->context
= peasycap
;
3742 purb
->start_frame
= 0;
3743 purb
->number_of_packets
= peasycap
->video_isoc_framesperdesc
;
3744 for (j
= 0; j
< peasycap
->video_isoc_framesperdesc
; j
++) {
3745 purb
->iso_frame_desc
[j
].offset
= j
* \
3746 peasycap
->video_isoc_maxframesize
;
3747 purb
->iso_frame_desc
[j
].length
= \
3748 peasycap
->video_isoc_maxframesize
;
3751 JOT(4, "allocation of %i struct urb done.\n", k
);
3752 /*--------------------------------------------------------------------------*/
3754 * SAVE POINTER peasycap IN THIS INTERFACE.
3756 /*--------------------------------------------------------------------------*/
3757 usb_set_intfdata(pusb_interface
, peasycap
);
3758 /*--------------------------------------------------------------------------*/
3760 * THE VIDEO DEVICE CAN BE REGISTERED NOW, AS IT IS READY.
3762 /*--------------------------------------------------------------------------*/
3763 #if !defined(EASYCAP_IS_VIDEODEV_CLIENT)
3764 if (0 != (usb_register_dev(pusb_interface
, &easycap_class
))) {
3765 err("Not able to get a minor for this device");
3766 usb_set_intfdata(pusb_interface
, NULL
);
3769 (peasycap
->registered_video
)++;
3770 SAY("easycap attached to minor #%d\n", pusb_interface
->minor
);
3772 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
3774 pvideo_device
= (struct video_device
*)\
3775 kzalloc(sizeof(struct video_device
), GFP_KERNEL
);
3776 if ((struct video_device
*)NULL
== pvideo_device
) {
3777 SAY("ERROR: Could not allocate structure video_device\n");
3780 if (VIDEO_DEVICE_MANY
<= video_device_many
) {
3781 SAY("ERROR: Too many /dev/videos\n");
3784 pvideo_array
[video_device_many
] = pvideo_device
; video_device_many
++;
3786 strcpy(&pvideo_device
->name
[0], "easycapdc60");
3787 #if defined(EASYCAP_NEEDS_V4L2_FOPS)
3788 pvideo_device
->fops
= &v4l2_fops
;
3790 pvideo_device
->fops
= &easycap_fops
;
3791 #endif /*EASYCAP_NEEDS_V4L2_FOPS*/
3792 pvideo_device
->minor
= -1;
3793 pvideo_device
->release
= (void *)(&videodev_release
);
3795 video_set_drvdata(pvideo_device
, (void *)peasycap
);
3797 rc
= video_register_device(pvideo_device
, VFL_TYPE_GRABBER
, -1);
3799 err("Not able to register with videodev");
3800 videodev_release(pvideo_device
);
3803 peasycap
->pvideo_device
= pvideo_device
;
3804 (peasycap
->registered_video
)++;
3805 JOT(4, "registered with videodev: %i=minor\n", \
3806 pvideo_device
->minor
);
3808 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
3809 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
3812 /*--------------------------------------------------------------------------*/
3814 * INTERFACE 1 IS THE AUDIO CONTROL INTERFACE
3815 * INTERFACE 2 IS THE AUDIO STREAMING INTERFACE
3817 /*--------------------------------------------------------------------------*/
3819 /*--------------------------------------------------------------------------*/
3821 * SAVE POINTER peasycap IN INTERFACE 1
3823 /*--------------------------------------------------------------------------*/
3824 usb_set_intfdata(pusb_interface
, peasycap
);
3825 JOT(4, "no initialization required for interface %i\n", \
3826 pusb_interface_descriptor
->bInterfaceNumber
);
3829 /*--------------------------------------------------------------------------*/
3832 SAY("MISTAKE: peasycap is NULL\n");
3836 SAY("ERROR: no viable audio_altsetting_on\n");
3839 peasycap
->audio_altsetting_on
= okalt
[isokalt
- 1];
3840 JOT(4, "%i=audio_altsetting_on <====\n", \
3841 peasycap
->audio_altsetting_on
);
3844 SAY("ERROR: no viable audio_endpointnumber\n");
3847 peasycap
->audio_endpointnumber
= okepn
[isokepn
- 1];
3848 JOT(4, "%i=audio_endpointnumber\n", \
3849 peasycap
->audio_endpointnumber
);
3852 SAY("ERROR: no viable audio_maxpacketsize\n");
3855 peasycap
->audio_isoc_maxframesize
= okmps
[isokmps
- 1];
3856 JOT(4, "%i=audio_isoc_maxframesize\n", \
3857 peasycap
->audio_isoc_maxframesize
);
3858 if (0 >= peasycap
->audio_isoc_maxframesize
) {
3859 SAY("ERROR: bad audio_isoc_maxframesize\n");
3862 if (9 == peasycap
->audio_isoc_maxframesize
) {
3863 peasycap
->ilk
|= 0x02;
3864 SAY("hardware is FOUR-CVBS\n");
3865 peasycap
->microphone
= true;
3866 peasycap
->audio_pages_per_fragment
= 4;
3867 } else if (256 == peasycap
->audio_isoc_maxframesize
) {
3868 peasycap
->ilk
&= ~0x02;
3869 SAY("hardware is CVBS+S-VIDEO\n");
3870 peasycap
->microphone
= false;
3871 peasycap
->audio_pages_per_fragment
= 4;
3873 SAY("hardware is unidentified:\n");
3874 SAY("%i=audio_isoc_maxframesize\n", \
3875 peasycap
->audio_isoc_maxframesize
);
3879 peasycap
->audio_bytes_per_fragment
= \
3880 peasycap
->audio_pages_per_fragment
* \
3882 peasycap
->audio_buffer_page_many
= (AUDIO_FRAGMENT_MANY
* \
3883 peasycap
->audio_pages_per_fragment
);
3885 JOT(4, "%6i=AUDIO_FRAGMENT_MANY\n", AUDIO_FRAGMENT_MANY
);
3886 JOT(4, "%6i=audio_pages_per_fragment\n", \
3887 peasycap
->audio_pages_per_fragment
);
3888 JOT(4, "%6i=audio_bytes_per_fragment\n", \
3889 peasycap
->audio_bytes_per_fragment
);
3890 JOT(4, "%6i=audio_buffer_page_many\n", \
3891 peasycap
->audio_buffer_page_many
);
3893 peasycap
->audio_isoc_framesperdesc
= 128;
3895 JOT(4, "%i=audio_isoc_framesperdesc\n", \
3896 peasycap
->audio_isoc_framesperdesc
);
3897 if (0 >= peasycap
->audio_isoc_framesperdesc
) {
3898 SAY("ERROR: bad audio_isoc_framesperdesc\n");
3902 peasycap
->audio_isoc_buffer_size
= \
3903 peasycap
->audio_isoc_maxframesize
* \
3904 peasycap
->audio_isoc_framesperdesc
;
3905 JOT(4, "%i=audio_isoc_buffer_size\n", \
3906 peasycap
->audio_isoc_buffer_size
);
3907 if (AUDIO_ISOC_BUFFER_SIZE
< \
3908 peasycap
->audio_isoc_buffer_size
) {
3909 SAY("MISTAKE: audio_isoc_buffer_size bigger "
3910 "than %li=AUDIO_ISOC_BUFFER_SIZE\n", \
3911 AUDIO_ISOC_BUFFER_SIZE
);
3916 if (-1 == peasycap
->audio_interface
) {
3917 SAY("MISTAKE: audio_interface is unset\n");
3920 if (-1 == peasycap
->audio_altsetting_on
) {
3921 SAY("MISTAKE: audio_altsetting_on is unset\n");
3924 if (-1 == peasycap
->audio_altsetting_off
) {
3925 SAY("MISTAKE: audio_interface_off is unset\n");
3928 if (-1 == peasycap
->audio_endpointnumber
) {
3929 SAY("MISTAKE: audio_endpointnumber is unset\n");
3932 if (-1 == peasycap
->audio_isoc_maxframesize
) {
3933 SAY("MISTAKE: audio_isoc_maxframesize is unset\n");
3936 if (-1 == peasycap
->audio_isoc_buffer_size
) {
3937 SAY("MISTAKE: audio_isoc_buffer_size is unset\n");
3940 /*---------------------------------------------------------------------------*/
3942 * ALLOCATE MEMORY FOR AUDIO BUFFERS. LISTS MUST BE INITIALIZED FIRST.
3944 /*---------------------------------------------------------------------------*/
3945 INIT_LIST_HEAD(&(peasycap
->urb_audio_head
));
3946 peasycap
->purb_audio_head
= &(peasycap
->urb_audio_head
);
3948 JOT(4, "allocating an audio buffer\n");
3949 JOT(4, ".... scattered over %i pages\n", \
3950 peasycap
->audio_buffer_page_many
);
3952 for (k
= 0; k
< peasycap
->audio_buffer_page_many
; k
++) {
3953 if ((void *)NULL
!= peasycap
->audio_buffer
[k
].pgo
) {
3954 SAY("ERROR: attempting to reallocate audio buffers\n");
3956 pbuf
= (void *) __get_free_page(GFP_KERNEL
);
3957 if ((void *)NULL
== pbuf
) {
3958 SAY("ERROR: Could not allocate audio " \
3959 "buffer page %i\n", k
);
3962 peasycap
->allocation_audio_page
+= 1;
3964 peasycap
->audio_buffer
[k
].pgo
= pbuf
;
3966 peasycap
->audio_buffer
[k
].pto
= peasycap
->audio_buffer
[k
].pgo
;
3969 peasycap
->audio_fill
= 0;
3970 peasycap
->audio_read
= 0;
3971 JOT(4, "allocation of audio buffer done: %i pages\n", k
);
3972 /*---------------------------------------------------------------------------*/
3973 JOT(4, "allocating %i isoc audio buffers of size %i\n", \
3974 AUDIO_ISOC_BUFFER_MANY
, peasycap
->audio_isoc_buffer_size
);
3975 JOT(4, ".... each occupying contiguous memory pages\n");
3977 for (k
= 0; k
< AUDIO_ISOC_BUFFER_MANY
; k
++) {
3978 pbuf
= (void *)__get_free_pages(GFP_KERNEL
, AUDIO_ISOC_ORDER
);
3980 SAY("ERROR: Could not allocate isoc audio buffer " \
3984 peasycap
->allocation_audio_page
+= \
3985 ((unsigned int)(0x01 << AUDIO_ISOC_ORDER
));
3987 peasycap
->audio_isoc_buffer
[k
].pgo
= pbuf
;
3988 peasycap
->audio_isoc_buffer
[k
].pto
= pbuf
+ \
3989 peasycap
->audio_isoc_buffer_size
;
3990 peasycap
->audio_isoc_buffer
[k
].kount
= k
;
3992 JOT(4, "allocation of isoc audio buffers done.\n");
3993 /*---------------------------------------------------------------------------*/
3995 * ALLOCATE AND INITIALIZE MULTIPLE struct urb ...
3997 /*---------------------------------------------------------------------------*/
3998 JOT(4, "allocating %i struct urb.\n", AUDIO_ISOC_BUFFER_MANY
);
3999 JOT(4, "using %i=peasycap->audio_isoc_framesperdesc\n", \
4000 peasycap
->audio_isoc_framesperdesc
);
4001 JOT(4, "using %i=peasycap->audio_isoc_maxframesize\n", \
4002 peasycap
->audio_isoc_maxframesize
);
4003 JOT(4, "using %i=peasycap->audio_isoc_buffer_size\n", \
4004 peasycap
->audio_isoc_buffer_size
);
4006 for (k
= 0; k
< AUDIO_ISOC_BUFFER_MANY
; k
++) {
4007 purb
= usb_alloc_urb(peasycap
->audio_isoc_framesperdesc
, \
4010 SAY("ERROR: usb_alloc_urb returned NULL for buffer " \
4014 peasycap
->allocation_audio_urb
+= 1 ;
4015 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
4016 pdata_urb
= kzalloc(sizeof(struct data_urb
), GFP_KERNEL
);
4017 if (NULL
== pdata_urb
) {
4018 SAY("ERROR: Could not allocate struct data_urb.\n");
4021 peasycap
->allocation_audio_struct
+= \
4022 sizeof(struct data_urb
);
4024 pdata_urb
->purb
= purb
;
4025 pdata_urb
->isbuf
= k
;
4026 pdata_urb
->length
= 0;
4027 list_add_tail(&(pdata_urb
->list_head
), \
4028 peasycap
->purb_audio_head
);
4029 /*---------------------------------------------------------------------------*/
4031 * ... AND INITIALIZE THEM
4033 /*---------------------------------------------------------------------------*/
4035 JOT(4, "initializing audio urbs thus:\n");
4036 JOT(4, " purb->interval = 1;\n");
4037 JOT(4, " purb->dev = peasycap->pusb_device;\n");
4038 JOT(4, " purb->pipe = usb_rcvisocpipe(peasycap->" \
4039 "pusb_device,%i);\n", \
4040 peasycap
->audio_endpointnumber
);
4041 JOT(4, " purb->transfer_flags = URB_ISO_ASAP;\n");
4042 JOT(4, " purb->transfer_buffer = " \
4043 "peasycap->audio_isoc_buffer[.].pgo;\n");
4044 JOT(4, " purb->transfer_buffer_length = %i;\n", \
4045 peasycap
->audio_isoc_buffer_size
);
4046 JOT(4, " purb->complete = easysnd_complete;\n");
4047 JOT(4, " purb->context = peasycap;\n");
4048 JOT(4, " purb->start_frame = 0;\n");
4049 JOT(4, " purb->number_of_packets = %i;\n", \
4050 peasycap
->audio_isoc_framesperdesc
);
4051 JOT(4, " for (j = 0; j < %i; j++)\n", \
4052 peasycap
->audio_isoc_framesperdesc
);
4054 JOT(4, " purb->iso_frame_desc[j].offset = j*%i;\n",\
4055 peasycap
->audio_isoc_maxframesize
);
4056 JOT(4, " purb->iso_frame_desc[j].length = %i;\n", \
4057 peasycap
->audio_isoc_maxframesize
);
4062 purb
->dev
= peasycap
->pusb_device
;
4063 purb
->pipe
= usb_rcvisocpipe(peasycap
->pusb_device
, \
4064 peasycap
->audio_endpointnumber
);
4065 purb
->transfer_flags
= URB_ISO_ASAP
;
4066 purb
->transfer_buffer
= peasycap
->audio_isoc_buffer
[k
].pgo
;
4067 purb
->transfer_buffer_length
= \
4068 peasycap
->audio_isoc_buffer_size
;
4069 purb
->complete
= easysnd_complete
;
4070 purb
->context
= peasycap
;
4071 purb
->start_frame
= 0;
4072 purb
->number_of_packets
= peasycap
->audio_isoc_framesperdesc
;
4073 for (j
= 0; j
< peasycap
->audio_isoc_framesperdesc
; j
++) {
4074 purb
->iso_frame_desc
[j
].offset
= j
* \
4075 peasycap
->audio_isoc_maxframesize
;
4076 purb
->iso_frame_desc
[j
].length
= \
4077 peasycap
->audio_isoc_maxframesize
;
4080 JOT(4, "allocation of %i struct urb done.\n", k
);
4081 /*---------------------------------------------------------------------------*/
4083 * SAVE POINTER peasycap IN THIS INTERFACE.
4085 /*---------------------------------------------------------------------------*/
4086 usb_set_intfdata(pusb_interface
, peasycap
);
4087 /*---------------------------------------------------------------------------*/
4089 * THE AUDIO DEVICE CAN BE REGISTERED NOW, AS IT IS READY.
4091 /*---------------------------------------------------------------------------*/
4092 rc
= usb_register_dev(pusb_interface
, &easysnd_class
);
4094 err("Not able to get a minor for this device.");
4095 usb_set_intfdata(pusb_interface
, NULL
);
4098 (peasycap
->registered_audio
)++;
4099 /*---------------------------------------------------------------------------*/
4101 * LET THE USER KNOW WHAT NODE THE AUDIO DEVICE IS ATTACHED TO.
4103 /*---------------------------------------------------------------------------*/
4104 SAY("easysnd attached to minor #%d\n", pusb_interface
->minor
);
4107 /*---------------------------------------------------------------------------*/
4109 * INTERFACES OTHER THAN 0, 1 AND 2 ARE UNEXPECTED
4111 /*---------------------------------------------------------------------------*/
4113 JOT(4, "ERROR: unexpected interface %i\n", bInterfaceNumber
);
4117 JOT(4, "ends successfully for interface %i\n", \
4118 pusb_interface_descriptor
->bInterfaceNumber
);
4121 /*****************************************************************************/
4122 /*---------------------------------------------------------------------------*/
4124 * WHEN THIS FUNCTION IS CALLED THE DEVICE HAS ALREADY BEEN PHYSICALLY
4126 * HENCE peasycap->pusb_device IS NO LONGER VALID AND MUST BE SET TO NULL.
4128 /*---------------------------------------------------------------------------*/
4130 easycap_usb_disconnect(struct usb_interface
*pusb_interface
)
4132 struct usb_host_interface
*pusb_host_interface
;
4133 struct usb_interface_descriptor
*pusb_interface_descriptor
;
4134 __u8 bInterfaceNumber
;
4135 struct easycap
*peasycap
;
4137 struct list_head
*plist_head
;
4138 struct data_urb
*pdata_urb
;
4143 if ((struct usb_interface
*)NULL
== pusb_interface
) {
4144 JOT(4, "ERROR: pusb_interface is NULL\n");
4147 pusb_host_interface
= pusb_interface
->cur_altsetting
;
4148 if ((struct usb_host_interface
*)NULL
== pusb_host_interface
) {
4149 JOT(4, "ERROR: pusb_host_interface is NULL\n");
4152 pusb_interface_descriptor
= &(pusb_host_interface
->desc
);
4153 if ((struct usb_interface_descriptor
*)NULL
== pusb_interface_descriptor
) {
4154 JOT(4, "ERROR: pusb_interface_descriptor is NULL\n");
4157 bInterfaceNumber
= pusb_interface_descriptor
->bInterfaceNumber
;
4158 minor
= pusb_interface
->minor
;
4159 JOT(4, "intf[%i]: minor=%i\n", bInterfaceNumber
, minor
);
4161 peasycap
= usb_get_intfdata(pusb_interface
);
4162 if ((struct easycap
*)NULL
== peasycap
)
4163 SAY("ERROR: peasycap is NULL\n");
4165 peasycap
->pusb_device
= (struct usb_device
*)NULL
;
4166 switch (bInterfaceNumber
) {
4167 /*---------------------------------------------------------------------------*/
4169 if ((struct list_head
*)NULL
!= peasycap
->purb_video_head
) {
4170 JOT(4, "killing video urbs\n");
4172 list_for_each(plist_head
, (peasycap
->purb_video_head
))
4174 pdata_urb
= list_entry(plist_head
, \
4175 struct data_urb
, list_head
);
4176 if ((struct data_urb
*)NULL
!= pdata_urb
) {
4177 if ((struct urb
*)NULL
!= \
4179 usb_kill_urb(pdata_urb
->purb
);
4184 JOT(4, "%i video urbs killed\n", m
);
4186 SAY("ERROR: peasycap->purb_video_head is NULL\n");
4189 /*---------------------------------------------------------------------------*/
4191 if ((struct list_head
*)NULL
!= peasycap
->purb_audio_head
) {
4192 JOT(4, "killing audio urbs\n");
4194 list_for_each(plist_head
, \
4195 (peasycap
->purb_audio_head
)) {
4196 pdata_urb
= list_entry(plist_head
, \
4197 struct data_urb
, list_head
);
4198 if ((struct data_urb
*)NULL
!= pdata_urb
) {
4199 if ((struct urb
*)NULL
!= \
4201 usb_kill_urb(pdata_urb
->purb
);
4206 JOT(4, "%i audio urbs killed\n", m
);
4208 SAY("ERROR: peasycap->purb_audio_head is NULL\n");
4211 /*---------------------------------------------------------------------------*/
4216 /*--------------------------------------------------------------------------*/
4220 /*--------------------------------------------------------------------------*/
4221 switch (bInterfaceNumber
) {
4223 #if !defined(EASYCAP_IS_VIDEODEV_CLIENT)
4224 if ((struct easycap
*)NULL
== peasycap
) {
4225 SAY("ERROR: peasycap has become NULL\n");
4228 usb_deregister_dev(pusb_interface
, &easycap_class
);
4229 (peasycap
->registered_video
)--;
4231 JOT(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber
);
4233 SAY("easycap detached from minor #%d\n", minor
);
4235 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
4237 if ((struct easycap
*)NULL
== peasycap
)
4238 SAY("ERROR: peasycap has become NULL\n");
4241 video_unregister_device(peasycap
->pvideo_device
);
4242 (peasycap
->registered_video
)--;
4244 JOT(4, "unregistered with videodev: %i=minor\n", \
4245 pvideo_device
->minor
);
4247 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
4248 #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
4254 usb_deregister_dev(pusb_interface
, &easysnd_class
);
4255 if ((struct easycap
*)NULL
!= peasycap
)
4256 (peasycap
->registered_audio
)--;
4258 JOT(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber
);
4261 SAY("easysnd detached from minor #%d\n", minor
);
4267 /*---------------------------------------------------------------------------*/
4269 * CALL easycap_delete() IF NO REMAINING REFERENCES TO peasycap
4271 /*---------------------------------------------------------------------------*/
4272 if ((struct easycap
*)NULL
== peasycap
) {
4273 SAY("ERROR: peasycap has become NULL\n");
4274 SAY("cannot call kref_put()\n");
4275 SAY("ending unsuccessfully: may cause memory leak\n");
4278 if (!peasycap
->kref
.refcount
.counter
) {
4279 SAY("ERROR: peasycap->kref.refcount.counter is zero " \
4280 "so cannot call kref_put()\n");
4281 SAY("ending unsuccessfully: may cause memory leak\n");
4284 JOT(4, "intf[%i]: kref_put() with %i=peasycap->kref.refcount.counter\n", \
4285 bInterfaceNumber
, (int)peasycap
->kref
.refcount
.counter
);
4286 kref_put(&peasycap
->kref
, easycap_delete
);
4287 JOT(4, "intf[%i]: kref_put() done.\n", bInterfaceNumber
);
4288 /*---------------------------------------------------------------------------*/
4293 /*****************************************************************************/
4295 easycap_module_init(void)
4299 SAY("========easycap=======\n");
4300 JOT(4, "begins. %i=debug\n", easycap_debug
);
4301 SAY("version: " EASYCAP_DRIVER_VERSION
"\n");
4302 /*---------------------------------------------------------------------------*/
4304 * REGISTER THIS DRIVER WITH THE USB SUBSYTEM.
4306 /*---------------------------------------------------------------------------*/
4307 JOT(4, "registering driver easycap\n");
4309 result
= usb_register(&easycap_usb_driver
);
4311 SAY("ERROR: usb_register returned %i\n", result
);
4316 /*****************************************************************************/
4318 easycap_module_exit(void)
4322 /*---------------------------------------------------------------------------*/
4324 * DEREGISTER THIS DRIVER WITH THE USB SUBSYTEM.
4326 /*---------------------------------------------------------------------------*/
4327 usb_deregister(&easycap_usb_driver
);
4331 /*****************************************************************************/
4333 module_init(easycap_module_init
);
4334 module_exit(easycap_module_exit
);
4336 MODULE_LICENSE("GPL");
4337 MODULE_AUTHOR("R.M. Thomas <rmthomas@sciolus.org>");
4338 MODULE_DESCRIPTION(EASYCAP_DRIVER_DESCRIPTION
);
4339 MODULE_VERSION(EASYCAP_DRIVER_VERSION
);
4340 #if defined(EASYCAP_DEBUG)
4341 MODULE_PARM_DESC(easycap_debug
, "debug: 0 (default), 1, 2,...");
4342 #endif /*EASYCAP_DEBUG*/
4343 /*****************************************************************************/