staging/easycap: Improve interface to the videodev module
The changes here represent an intermediate step towards bringing the driver within the V4L2 framework. Signed-off-by: Mike Thomas <rmthomas@sciolus.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
ae59dad4fe
commit
268dfede46
@@ -24,6 +24,9 @@ Two kinds of EasyCAP have this USB ID, namely:
|
|||||||
BUILD OPTIONS AND DEPENDENCIES
|
BUILD OPTIONS AND DEPENDENCIES
|
||||||
------------------------------
|
------------------------------
|
||||||
|
|
||||||
|
Unless EASYCAP_DEBUG is defined during compilation it will not be possible
|
||||||
|
to select a debug level at the time of module installation.
|
||||||
|
|
||||||
If the parameter EASYCAP_IS_VIDEODEV_CLIENT is undefined during compilation
|
If the parameter EASYCAP_IS_VIDEODEV_CLIENT is undefined during compilation
|
||||||
the built module is entirely independent of the videodev module, and when
|
the built module is entirely independent of the videodev module, and when
|
||||||
the EasyCAP is physically plugged into a USB port the special files
|
the EasyCAP is physically plugged into a USB port the special files
|
||||||
@@ -33,41 +36,54 @@ respectively.
|
|||||||
If the parameter EASYCAP_IS_VIDEODEV_CLIENT is defined during compilation
|
If the parameter EASYCAP_IS_VIDEODEV_CLIENT is defined during compilation
|
||||||
the built easycap module is configured to register with the videodev module,
|
the built easycap module is configured to register with the videodev module,
|
||||||
in which case the special files created when the EasyCAP is plugged in are
|
in which case the special files created when the EasyCAP is plugged in are
|
||||||
/dev/video0 and /dev/easysnd0. Use of the easycap module as a client of
|
/dev/video0 and /dev/easysnd0.
|
||||||
the videodev module has received very little testing as of June 2010.
|
|
||||||
|
|
||||||
|
During in-tree builds the following should should be defined whenever the
|
||||||
|
parameter EASYCAP_IS_VIDEODEV_CLIENT is defined:
|
||||||
|
|
||||||
KNOWN BUILD PROBLEMS
|
EASYCAP_NEEDS_V4L2_DEVICE_H
|
||||||
--------------------
|
EASYCAP_NEEDS_V4L2_FOPS
|
||||||
|
EASYCAP_NEEDS_UNLOCKED_IOCTL
|
||||||
|
|
||||||
(1) Recent gcc versions may generate the message:
|
If the build is performed out-of-tree against older kernels the parameters
|
||||||
|
to be defined depend on the kernel version in a way which will not be
|
||||||
warning: the frame size of .... bytes is larger than 1024 bytes
|
discussed here.
|
||||||
|
|
||||||
This warning can be suppressed by specifying in the Makefile:
|
|
||||||
|
|
||||||
EXTRA_CFLAGS += -Wframe-larger-than=8192
|
|
||||||
|
|
||||||
but it would be preferable to remove the cause of the warning.
|
|
||||||
|
|
||||||
|
|
||||||
KNOWN RUNTIME ISSUES
|
KNOWN RUNTIME ISSUES
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
(1) Randomly (maybe 5 to 10% of occasions) the driver fails to produce any
|
(1) Intentionally, this driver will not stream material which is unambiguously
|
||||||
output at start-up. Closing mplayer (or whatever the user program is) and
|
identified by the hardware as copy-protected. Normal video output will be
|
||||||
restarting it restores normal performance without any other remedial action
|
present for about a minute but will then freeze when this situation arises.
|
||||||
being necessary. The reason for this is not known.
|
|
||||||
|
|
||||||
(2) Intentionally, this driver will not stream material which is unambiguously
|
(2) The controls for luminance, contrast, saturation, hue and volume may not
|
||||||
identified by the hardware as copy-protected. The video output will freeze
|
|
||||||
within about a minute when this situation arises.
|
|
||||||
|
|
||||||
(3) The controls for luminance, contrast, saturation, hue and volume may not
|
|
||||||
always work properly.
|
always work properly.
|
||||||
|
|
||||||
(4) Reduced-resolution S-Video seems to suffer from moire artefacts. No
|
(3) Reduced-resolution S-Video seems to suffer from moire artefacts.
|
||||||
attempt has yet been made to rememdy this.
|
|
||||||
|
|
||||||
|
INPUT NUMBERING
|
||||||
|
---------------
|
||||||
|
|
||||||
|
For the EasyCAP with S-VIDEO input cable the driver regards a request for
|
||||||
|
inputs numbered 0 or 1 as referring to CVBS and a request for input
|
||||||
|
numbered 5 as referring to S-VIDEO.
|
||||||
|
|
||||||
|
For the EasyCAP with four CVBS inputs the driver expects to be asked for
|
||||||
|
any one of inputs numbered 1,2,3,4. If input 0 is asked for, it is
|
||||||
|
interpreted as input 1.
|
||||||
|
|
||||||
|
|
||||||
|
MODULE PARAMETERS
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
Three module parameters are defined:
|
||||||
|
|
||||||
|
debug the easycap module is configured at diagnostic level n (0 to 9)
|
||||||
|
gain audio gain level n (0 to 31, default is 16)
|
||||||
|
bars 0 => testcard bars when incoming video signal is lost
|
||||||
|
1 => testcard bars when incoming video signal is lost (default)
|
||||||
|
|
||||||
|
|
||||||
SUPPORTED TV STANDARDS AND RESOLUTIONS
|
SUPPORTED TV STANDARDS AND RESOLUTIONS
|
||||||
@@ -82,18 +98,29 @@ usable as (for example) the "norm=" parameter in the mplayer command:
|
|||||||
PAL_60, NTSC_443,
|
PAL_60, NTSC_443,
|
||||||
PAL_M.
|
PAL_M.
|
||||||
|
|
||||||
|
In addition, the driver offers "custom" pseudo-standards with a framerate
|
||||||
|
which is 20% of the usual framerate. These pseudo-standards are named:
|
||||||
|
|
||||||
|
PAL_BGHIN_SLOW, NTSC_N_443_SLOW,
|
||||||
|
PAL_Nc_SLOW, NTSC_N_SLOW,
|
||||||
|
SECAM_SLOW, NTSC_M_SLOW, NTSC_M_JP_SLOW,
|
||||||
|
PAL_60_SLOW, NTSC_443_SLOW,
|
||||||
|
PAL_M_SLOW.
|
||||||
|
|
||||||
|
|
||||||
The available picture sizes are:
|
The available picture sizes are:
|
||||||
|
|
||||||
at 25 frames per second: 720x576, 704x576, 640x480, 360x288, 320x240;
|
at 25 frames per second: 720x576, 704x576, 640x480, 360x288, 320x240;
|
||||||
at 30 frames per second: 720x480, 640x480, 360x240, 320x240;
|
at 30 frames per second: 720x480, 640x480, 360x240, 320x240.
|
||||||
|
|
||||||
|
|
||||||
WHAT'S TESTED AND WHAT'S NOT
|
WHAT'S TESTED AND WHAT'S NOT
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
This driver is known to work with mplayer, mencoder, tvtime and sufficiently
|
This driver is known to work with mplayer, mencoder, tvtime, zoneminder,
|
||||||
recent versions of vlc. An interface to ffmpeg is implemented, but serious
|
xawtv, gstreamer and sufficiently recent versions of vlc. An interface
|
||||||
audio-video synchronization problems remain.
|
to ffmpeg is implemented, but serious audio-video synchronization problems
|
||||||
|
remain.
|
||||||
|
|
||||||
The driver is designed to support all the TV standards accepted by the
|
The driver is designed to support all the TV standards accepted by the
|
||||||
hardware, but as yet it has actually been tested on only a few of these.
|
hardware, but as yet it has actually been tested on only a few of these.
|
||||||
@@ -101,10 +128,7 @@ hardware, but as yet it has actually been tested on only a few of these.
|
|||||||
I have been unable to test and calibrate the S-video input myself because I
|
I have been unable to test and calibrate the S-video input myself because I
|
||||||
do not possess any equipment with S-video output.
|
do not possess any equipment with S-video output.
|
||||||
|
|
||||||
This driver does not understand the V4L1 IOCTL commands, so programs such
|
This driver does not understand the V4L1 IOCTL commands.
|
||||||
as camorama are not compatible. There are reports that the driver does
|
|
||||||
work with sufficiently recent (V4L2) versions of zoneminder, but I have not
|
|
||||||
attempted to confirm this myself.
|
|
||||||
|
|
||||||
|
|
||||||
UDEV RULES
|
UDEV RULES
|
||||||
@@ -120,6 +144,17 @@ ATTRS{idVendor}=="05e1", ATTRS{idProduct}=="0408", \
|
|||||||
LABEL="easycap_rules_end"
|
LABEL="easycap_rules_end"
|
||||||
|
|
||||||
|
|
||||||
|
MODPROBE CONFIGURATION
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
The easycap module is in competition with the module snd-usb-audio for the
|
||||||
|
EasyCAP's audio channel, and its installation can be aided by providing a
|
||||||
|
file in directory /etc/modprobe.d with content:
|
||||||
|
|
||||||
|
options easycap gain=16 bars=1
|
||||||
|
install easycap /sbin/rmmod snd-usb-audio; /sbin/modprobe --ignore-install easycap
|
||||||
|
|
||||||
|
|
||||||
ACKNOWLEGEMENTS AND REFERENCES
|
ACKNOWLEGEMENTS AND REFERENCES
|
||||||
------------------------------
|
------------------------------
|
||||||
This driver makes use of information contained in the Syntek Semicon DC-1125
|
This driver makes use of information contained in the Syntek Semicon DC-1125
|
||||||
|
@@ -33,6 +33,7 @@
|
|||||||
* EASYCAP_NEEDS_USBVIDEO_H
|
* EASYCAP_NEEDS_USBVIDEO_H
|
||||||
* EASYCAP_NEEDS_V4L2_DEVICE_H
|
* EASYCAP_NEEDS_V4L2_DEVICE_H
|
||||||
* EASYCAP_NEEDS_V4L2_FOPS
|
* EASYCAP_NEEDS_V4L2_FOPS
|
||||||
|
* EASYCAP_NEEDS_UNLOCKED_IOCTL
|
||||||
*
|
*
|
||||||
* IF REQUIRED THEY MUST BE EXTERNALLY DEFINED, FOR EXAMPLE AS COMPILER
|
* IF REQUIRED THEY MUST BE EXTERNALLY DEFINED, FOR EXAMPLE AS COMPILER
|
||||||
* OPTIONS.
|
* OPTIONS.
|
||||||
@@ -81,25 +82,14 @@
|
|||||||
|
|
||||||
/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
|
/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
|
||||||
#if defined(EASYCAP_IS_VIDEODEV_CLIENT)
|
#if defined(EASYCAP_IS_VIDEODEV_CLIENT)
|
||||||
#if (!defined(__OLD_VIDIOC_))
|
|
||||||
#define __OLD_VIDIOC_
|
|
||||||
#endif /* !defined(__OLD_VIDIOC_) */
|
|
||||||
|
|
||||||
#include <media/v4l2-dev.h>
|
#include <media/v4l2-dev.h>
|
||||||
|
|
||||||
#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H)
|
#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H)
|
||||||
#include <media/v4l2-device.h>
|
#include <media/v4l2-device.h>
|
||||||
#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/
|
#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/
|
||||||
#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
|
#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
|
||||||
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
|
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
|
||||||
|
|
||||||
#if (!defined(__OLD_VIDIOC_))
|
|
||||||
#define __OLD_VIDIOC_
|
|
||||||
#endif /* !defined(__OLD_VIDIOC_) */
|
|
||||||
#include <linux/videodev2.h>
|
#include <linux/videodev2.h>
|
||||||
|
|
||||||
#include <linux/soundcard.h>
|
#include <linux/soundcard.h>
|
||||||
|
|
||||||
#if defined(EASYCAP_NEEDS_USBVIDEO_H)
|
#if defined(EASYCAP_NEEDS_USBVIDEO_H)
|
||||||
#include <config/video/usbvideo.h>
|
#include <config/video/usbvideo.h>
|
||||||
#endif /*EASYCAP_NEEDS_USBVIDEO_H*/
|
#endif /*EASYCAP_NEEDS_USBVIDEO_H*/
|
||||||
@@ -110,7 +100,6 @@
|
|||||||
|
|
||||||
#define STRINGIZE_AGAIN(x) #x
|
#define STRINGIZE_AGAIN(x) #x
|
||||||
#define STRINGIZE(x) STRINGIZE_AGAIN(x)
|
#define STRINGIZE(x) STRINGIZE_AGAIN(x)
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/* VENDOR, PRODUCT: Syntek Semiconductor Co., Ltd
|
/* VENDOR, PRODUCT: Syntek Semiconductor Co., Ltd
|
||||||
*
|
*
|
||||||
@@ -305,6 +294,8 @@ int hue_ok;
|
|||||||
*/
|
*/
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
struct easycap {
|
struct easycap {
|
||||||
|
#define TELLTALE "expectedstring"
|
||||||
|
char telltale[16];
|
||||||
int isdongle;
|
int isdongle;
|
||||||
|
|
||||||
/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
|
/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
|
||||||
@@ -501,7 +492,6 @@ long easycap_ioctl_noinode(struct file *, unsigned int, \
|
|||||||
unsigned long);
|
unsigned long);
|
||||||
int easycap_ioctl(struct inode *, struct file *, unsigned int, \
|
int easycap_ioctl(struct inode *, struct file *, unsigned int, \
|
||||||
unsigned long);
|
unsigned long);
|
||||||
|
|
||||||
/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
|
/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
|
||||||
#if defined(EASYCAP_IS_VIDEODEV_CLIENT)
|
#if defined(EASYCAP_IS_VIDEODEV_CLIENT)
|
||||||
int easycap_open_noinode(struct file *);
|
int easycap_open_noinode(struct file *);
|
||||||
|
@@ -977,9 +977,13 @@ if (NULL == file) {
|
|||||||
}
|
}
|
||||||
peasycap = file->private_data;
|
peasycap = file->private_data;
|
||||||
if (NULL == peasycap) {
|
if (NULL == peasycap) {
|
||||||
SAY("ERROR: peasycap is NULL.\n");
|
SAY("ERROR: peasycap is NULL\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
|
||||||
|
SAY("ERROR: bad peasycap\n");
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
p = peasycap->pusb_device;
|
p = peasycap->pusb_device;
|
||||||
if (NULL == p) {
|
if (NULL == p) {
|
||||||
SAM("ERROR: peasycap->pusb_device is NULL\n");
|
SAM("ERROR: peasycap->pusb_device is NULL\n");
|
||||||
@@ -1012,6 +1016,11 @@ if (0 <= kd && DONGLE_MANY > kd) {
|
|||||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
}
|
}
|
||||||
|
if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
|
||||||
|
SAY("ERROR: bad peasycap\n");
|
||||||
|
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
p = peasycap->pusb_device;
|
p = peasycap->pusb_device;
|
||||||
if (NULL == peasycap->pusb_device) {
|
if (NULL == peasycap->pusb_device) {
|
||||||
SAM("ERROR: peasycap->pusb_device is NULL\n");
|
SAM("ERROR: peasycap->pusb_device is NULL\n");
|
||||||
@@ -2297,7 +2306,7 @@ case VIDIOC_DQBUF:
|
|||||||
((long long int)(timeval.tv_sec - \
|
((long long int)(timeval.tv_sec - \
|
||||||
timeval2.tv_sec)) + \
|
timeval2.tv_sec)) + \
|
||||||
(long long int)(timeval.tv_usec - \
|
(long long int)(timeval.tv_usec - \
|
||||||
timeval2.tv_usec);
|
timeval2.tv_usec);
|
||||||
sdr = signed_div(fudge, 1000);
|
sdr = signed_div(fudge, 1000);
|
||||||
sll = sdr.quotient;
|
sll = sdr.quotient;
|
||||||
ull = sdr.remainder;
|
ull = sdr.remainder;
|
||||||
@@ -2317,6 +2326,8 @@ case VIDIOC_DQBUF:
|
|||||||
JOM(16, " %10i=bytesused\n", v4l2_buffer.bytesused);
|
JOM(16, " %10i=bytesused\n", v4l2_buffer.bytesused);
|
||||||
JOM(16, " 0x%08X=flags\n", v4l2_buffer.flags);
|
JOM(16, " 0x%08X=flags\n", v4l2_buffer.flags);
|
||||||
JOM(16, " %10i=field\n", v4l2_buffer.field);
|
JOM(16, " %10i=field\n", v4l2_buffer.field);
|
||||||
|
JOM(16, " %10li=timestamp.tv_sec\n", \
|
||||||
|
(long)v4l2_buffer.timestamp.tv_sec);
|
||||||
JOM(16, " %10li=timestamp.tv_usec\n", \
|
JOM(16, " %10li=timestamp.tv_usec\n", \
|
||||||
(long)v4l2_buffer.timestamp.tv_usec);
|
(long)v4l2_buffer.timestamp.tv_usec);
|
||||||
JOM(16, " %10i=sequence\n", v4l2_buffer.sequence);
|
JOM(16, " %10i=sequence\n", v4l2_buffer.sequence);
|
||||||
@@ -2528,6 +2539,10 @@ if (NULL == peasycap) {
|
|||||||
SAY("ERROR: peasycap is NULL.\n");
|
SAY("ERROR: peasycap is NULL.\n");
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
|
||||||
|
SAY("ERROR: bad peasycap\n");
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
p = peasycap->pusb_device;
|
p = peasycap->pusb_device;
|
||||||
if (NULL == p) {
|
if (NULL == p) {
|
||||||
SAM("ERROR: peasycap->pusb_device is NULL\n");
|
SAM("ERROR: peasycap->pusb_device is NULL\n");
|
||||||
@@ -2560,6 +2575,11 @@ if (0 <= kd && DONGLE_MANY > kd) {
|
|||||||
mutex_unlock(&easycap_dongle[kd].mutex_audio);
|
mutex_unlock(&easycap_dongle[kd].mutex_audio);
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
}
|
}
|
||||||
|
if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
|
||||||
|
SAY("ERROR: bad peasycap\n");
|
||||||
|
mutex_unlock(&easycap_dongle[kd].mutex_audio);
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
p = peasycap->pusb_device;
|
p = peasycap->pusb_device;
|
||||||
if (NULL == peasycap->pusb_device) {
|
if (NULL == peasycap->pusb_device) {
|
||||||
SAM("ERROR: peasycap->pusb_device is NULL\n");
|
SAM("ERROR: peasycap->pusb_device is NULL\n");
|
||||||
@@ -2795,3 +2815,5 @@ mutex_unlock(&easycap_dongle[kd].mutex_audio);
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
@@ -93,16 +93,15 @@ const struct file_operations easycap_fops = {
|
|||||||
.llseek = no_llseek,
|
.llseek = no_llseek,
|
||||||
};
|
};
|
||||||
struct vm_operations_struct easycap_vm_ops = {
|
struct vm_operations_struct easycap_vm_ops = {
|
||||||
.open = easycap_vma_open,
|
.open = easycap_vma_open,
|
||||||
.close = easycap_vma_close,
|
.close = easycap_vma_close,
|
||||||
.fault = easycap_vma_fault,
|
.fault = easycap_vma_fault,
|
||||||
};
|
};
|
||||||
struct usb_class_driver easycap_class = {
|
struct usb_class_driver easycap_class = {
|
||||||
.name = "usb/easycap%d",
|
.name = "usb/easycap%d",
|
||||||
.fops = &easycap_fops,
|
.fops = &easycap_fops,
|
||||||
.minor_base = USB_SKEL_MINOR_BASE,
|
.minor_base = USB_SKEL_MINOR_BASE,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
|
/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
|
||||||
#if defined(EASYCAP_IS_VIDEODEV_CLIENT)
|
#if defined(EASYCAP_IS_VIDEODEV_CLIENT)
|
||||||
#if defined(EASYCAP_NEEDS_V4L2_FOPS)
|
#if defined(EASYCAP_NEEDS_V4L2_FOPS)
|
||||||
@@ -121,7 +120,6 @@ const struct v4l2_file_operations v4l2_fops = {
|
|||||||
#endif /*EASYCAP_NEEDS_V4L2_FOPS*/
|
#endif /*EASYCAP_NEEDS_V4L2_FOPS*/
|
||||||
#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
|
#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
|
||||||
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
|
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
/*
|
/*
|
||||||
* PARAMETERS USED WHEN REGISTERING THE AUDIO INTERFACE
|
* PARAMETERS USED WHEN REGISTERING THE AUDIO INTERFACE
|
||||||
@@ -147,7 +145,7 @@ struct usb_class_driver easysnd_class = {
|
|||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/*
|
/*
|
||||||
* THIS ROUTINE DOES NOT DETECT MULTIPLE OCCURRENCES OF POINTER peasycap
|
* THIS ROUTINE DOES NOT DETECT DUPLICATE OCCURRENCES OF POINTER peasycap
|
||||||
*/
|
*/
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
int
|
int
|
||||||
@@ -215,6 +213,10 @@ if (NULL == peasycap) {
|
|||||||
SAY("ERROR: peasycap is NULL\n");
|
SAY("ERROR: peasycap is NULL\n");
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
|
||||||
|
SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap);
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
if (NULL == peasycap->pusb_device) {
|
if (NULL == peasycap->pusb_device) {
|
||||||
SAM("ERROR: peasycap->pusb_device is NULL\n");
|
SAM("ERROR: peasycap->pusb_device is NULL\n");
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
@@ -838,6 +840,10 @@ if (NULL == peasycap) {
|
|||||||
SAY("ending unsuccessfully\n");
|
SAY("ending unsuccessfully\n");
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
|
||||||
|
SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap);
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
if (0 != kill_video_urbs(peasycap)) {
|
if (0 != kill_video_urbs(peasycap)) {
|
||||||
SAM("ERROR: kill_video_urbs() failed\n");
|
SAM("ERROR: kill_video_urbs() failed\n");
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
@@ -867,6 +873,10 @@ if (NULL == peasycap) {
|
|||||||
SAY("ending unsuccessfully\n");
|
SAY("ending unsuccessfully\n");
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
|
||||||
|
SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap);
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
if (0 != kill_video_urbs(peasycap)) {
|
if (0 != kill_video_urbs(peasycap)) {
|
||||||
SAM("ERROR: kill_video_urbs() failed\n");
|
SAM("ERROR: kill_video_urbs() failed\n");
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
@@ -904,6 +914,10 @@ if (NULL == peasycap) {
|
|||||||
SAM("ERROR: peasycap is NULL: cannot perform deletions\n");
|
SAM("ERROR: peasycap is NULL: cannot perform deletions\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
|
||||||
|
SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap);
|
||||||
|
return;
|
||||||
|
}
|
||||||
kd = isdongle(peasycap);
|
kd = isdongle(peasycap);
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/*
|
/*
|
||||||
@@ -1026,8 +1040,6 @@ if ((struct list_head *)NULL != peasycap->purb_audio_head) {
|
|||||||
JOM(4, "%i audio data_urb structures freed\n", m);
|
JOM(4, "%i audio data_urb structures freed\n", m);
|
||||||
JOM(4, "setting peasycap->purb_audio_head=NULL\n");
|
JOM(4, "setting peasycap->purb_audio_head=NULL\n");
|
||||||
peasycap->purb_audio_head = (struct list_head *)NULL;
|
peasycap->purb_audio_head = (struct list_head *)NULL;
|
||||||
} else {
|
|
||||||
JOM(4, "peasycap->purb_audio_head is NULL\n");
|
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
JOM(4, "freeing audio isoc buffers.\n");
|
JOM(4, "freeing audio isoc buffers.\n");
|
||||||
@@ -1108,6 +1120,10 @@ if (NULL == peasycap) {
|
|||||||
SAY("ERROR: peasycap is NULL\n");
|
SAY("ERROR: peasycap is NULL\n");
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
|
||||||
|
SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap);
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
if (NULL == peasycap->pusb_device) {
|
if (NULL == peasycap->pusb_device) {
|
||||||
SAY("ERROR: peasycap->pusb_device is NULL\n");
|
SAY("ERROR: peasycap->pusb_device is NULL\n");
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
@@ -1140,10 +1156,16 @@ if (0 <= kd && DONGLE_MANY > kd) {
|
|||||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
}
|
}
|
||||||
|
if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
|
||||||
|
SAY("ERROR: bad peasycap: 0x%08lX\n", \
|
||||||
|
(unsigned long int) peasycap);
|
||||||
|
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||||
|
return -ERESTARTSYS;
|
||||||
|
}
|
||||||
if (NULL == peasycap->pusb_device) {
|
if (NULL == peasycap->pusb_device) {
|
||||||
SAM("ERROR: peasycap->pusb_device is NULL\n");
|
SAM("ERROR: peasycap->pusb_device is NULL\n");
|
||||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
/*-------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------*/
|
||||||
@@ -2687,11 +2709,16 @@ easycap_vma_open(struct vm_area_struct *pvma)
|
|||||||
struct easycap *peasycap;
|
struct easycap *peasycap;
|
||||||
|
|
||||||
peasycap = pvma->vm_private_data;
|
peasycap = pvma->vm_private_data;
|
||||||
if (NULL != peasycap)
|
if (NULL == peasycap) {
|
||||||
peasycap->vma_many++;
|
SAY("ERROR: peasycap is NULL\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
|
||||||
|
SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
peasycap->vma_many++;
|
||||||
JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many);
|
JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@@ -2701,10 +2728,16 @@ easycap_vma_close(struct vm_area_struct *pvma)
|
|||||||
struct easycap *peasycap;
|
struct easycap *peasycap;
|
||||||
|
|
||||||
peasycap = pvma->vm_private_data;
|
peasycap = pvma->vm_private_data;
|
||||||
if (NULL != peasycap) {
|
if (NULL == peasycap) {
|
||||||
peasycap->vma_many--;
|
SAY("ERROR: peasycap is NULL\n");
|
||||||
JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many);
|
return;
|
||||||
}
|
}
|
||||||
|
if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
|
||||||
|
SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
peasycap->vma_many--;
|
||||||
|
JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@@ -2820,10 +2853,12 @@ if (NULL == peasycap) {
|
|||||||
SAY("ERROR: easycap_complete(): peasycap is NULL\n");
|
SAY("ERROR: easycap_complete(): peasycap is NULL\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
|
||||||
|
SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (peasycap->video_eof)
|
if (peasycap->video_eof)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < VIDEO_ISOC_BUFFER_MANY; i++)
|
for (i = 0; i < VIDEO_ISOC_BUFFER_MANY; i++)
|
||||||
if (purb->transfer_buffer == peasycap->video_isoc_buffer[i].pgo)
|
if (purb->transfer_buffer == peasycap->video_isoc_buffer[i].pgo)
|
||||||
break;
|
break;
|
||||||
@@ -3545,6 +3580,7 @@ if (0 == bInterfaceNumber) {
|
|||||||
* PERFORM URGENT INTIALIZATIONS ...
|
* PERFORM URGENT INTIALIZATIONS ...
|
||||||
*/
|
*/
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
strcpy(&peasycap->telltale[0], TELLTALE);
|
||||||
kref_init(&peasycap->kref);
|
kref_init(&peasycap->kref);
|
||||||
JOM(8, "intf[%i]: after kref_init(..._video) " \
|
JOM(8, "intf[%i]: after kref_init(..._video) " \
|
||||||
"%i=peasycap->kref.refcount.counter\n", \
|
"%i=peasycap->kref.refcount.counter\n", \
|
||||||
@@ -4299,6 +4335,26 @@ case 0: {
|
|||||||
*/
|
*/
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
usb_set_intfdata(pusb_interface, peasycap);
|
usb_set_intfdata(pusb_interface, peasycap);
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
* IT IS ESSENTIAL TO INITIALIZE THE HARDWARE BEFORE, RATHER THAN AFTER,
|
||||||
|
* THE DEVICE IS REGISTERED, BECAUSE SOME VERSIONS OF THE videodev MODULE
|
||||||
|
* CALL easycap_open() IMMEDIATELY AFTER REGISTRATION, CAUSING A CLASH.
|
||||||
|
* BEWARE.
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#if defined(PREFER_NTSC)
|
||||||
|
peasycap->ntsc = true;
|
||||||
|
JOM(8, "defaulting initially to NTSC\n");
|
||||||
|
#else
|
||||||
|
peasycap->ntsc = false;
|
||||||
|
JOM(8, "defaulting initially to PAL\n");
|
||||||
|
#endif /*PREFER_NTSC*/
|
||||||
|
rc = reset(peasycap);
|
||||||
|
if (0 != rc) {
|
||||||
|
SAM("ERROR: reset() returned %i\n", rc);
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
/*
|
/*
|
||||||
* THE VIDEO DEVICE CAN BE REGISTERED NOW, AS IT IS READY.
|
* THE VIDEO DEVICE CAN BE REGISTERED NOW, AS IT IS READY.
|
||||||
@@ -4687,6 +4743,13 @@ struct easycap *peasycap;
|
|||||||
struct list_head *plist_head;
|
struct list_head *plist_head;
|
||||||
struct data_urb *pdata_urb;
|
struct data_urb *pdata_urb;
|
||||||
int minor, m, kd;
|
int minor, m, kd;
|
||||||
|
/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
|
||||||
|
#if defined(EASYCAP_IS_VIDEODEV_CLIENT)
|
||||||
|
#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H)
|
||||||
|
struct v4l2_device *pv4l2_device;
|
||||||
|
#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/
|
||||||
|
#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
|
||||||
|
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
|
||||||
|
|
||||||
JOT(4, "\n");
|
JOT(4, "\n");
|
||||||
|
|
||||||
@@ -4717,6 +4780,38 @@ if (NULL == peasycap) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
|
||||||
|
#
|
||||||
|
/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
|
||||||
|
#else
|
||||||
|
#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H)
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
* SOME VERSIONS OF THE videodev MODULE OVERWRITE THE DATA WHICH HAS
|
||||||
|
* BEEN WRITTEN BY THE CALL TO usb_set_intfdata() IN easycap_usb_probe(),
|
||||||
|
* REPLACING IT WITH A POINTER TO THE EMBEDDED v4l2_device STRUCTURE.
|
||||||
|
* TO DETECT THIS, THE STRING IN THE easycap.telltale[] BUFFER IS CHECKED.
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
|
||||||
|
pv4l2_device = usb_get_intfdata(pusb_interface);
|
||||||
|
if ((struct v4l2_device *)NULL == pv4l2_device) {
|
||||||
|
SAY("ERROR: pv4l2_device is NULL\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
peasycap = (struct easycap *) \
|
||||||
|
container_of(pv4l2_device, struct easycap, v4l2_device);
|
||||||
|
}
|
||||||
|
#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/
|
||||||
|
#
|
||||||
|
#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
|
||||||
|
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
|
||||||
|
SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
/*
|
/*
|
||||||
* IF THE WAIT QUEUES ARE NOT CLEARED A DEADLOCK IS POSSIBLE. BEWARE.
|
* IF THE WAIT QUEUES ARE NOT CLEARED A DEADLOCK IS POSSIBLE. BEWARE.
|
||||||
*/
|
*/
|
||||||
@@ -4806,14 +4901,28 @@ case 0: {
|
|||||||
JOM(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber);
|
JOM(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber);
|
||||||
SAM("easycap detached from minor #%d\n", minor);
|
SAM("easycap detached from minor #%d\n", minor);
|
||||||
}
|
}
|
||||||
/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
|
/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
|
||||||
#else
|
#else
|
||||||
|
#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H)
|
||||||
|
if (!peasycap->v4l2_device.name[0]) {
|
||||||
|
SAM("ERROR: peasycap->v4l2_device.name is empty\n");
|
||||||
|
if (0 <= kd && DONGLE_MANY > kd)
|
||||||
|
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
v4l2_device_disconnect(&peasycap->v4l2_device);
|
||||||
|
JOM(4, "v4l2_device_disconnect() OK\n");
|
||||||
|
v4l2_device_unregister(&peasycap->v4l2_device);
|
||||||
|
JOM(4, "v4l2_device_unregister() OK\n");
|
||||||
|
#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/
|
||||||
|
|
||||||
video_unregister_device(&peasycap->video_device);
|
video_unregister_device(&peasycap->video_device);
|
||||||
JOM(4, "unregistered with videodev: %i=minor\n", \
|
JOM(4, "intf[%i]: video_unregister_device() OK\n", bInterfaceNumber);
|
||||||
peasycap->video_device.minor);
|
|
||||||
(peasycap->registered_video)--;
|
(peasycap->registered_video)--;
|
||||||
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
|
JOM(4, "unregistered with videodev: %i=minor\n", minor);
|
||||||
#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
|
#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
|
||||||
|
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
|
||||||
|
|
||||||
if (0 <= kd && DONGLE_MANY > kd) {
|
if (0 <= kd && DONGLE_MANY > kd) {
|
||||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||||
JOM(4, "unlocked easycap_dongle[%i].mutex_video\n", kd);
|
JOM(4, "unlocked easycap_dongle[%i].mutex_video\n", kd);
|
||||||
@@ -4941,7 +5050,7 @@ MODULE_AUTHOR("R.M. Thomas <rmthomas@sciolus.org>");
|
|||||||
MODULE_DESCRIPTION(EASYCAP_DRIVER_DESCRIPTION);
|
MODULE_DESCRIPTION(EASYCAP_DRIVER_DESCRIPTION);
|
||||||
MODULE_VERSION(EASYCAP_DRIVER_VERSION);
|
MODULE_VERSION(EASYCAP_DRIVER_VERSION);
|
||||||
#if defined(EASYCAP_DEBUG)
|
#if defined(EASYCAP_DEBUG)
|
||||||
MODULE_PARM_DESC(debug, "Debug level: 0 (default),1,2,...");
|
MODULE_PARM_DESC(debug, "Debug level: 0(default),1,2,...,9");
|
||||||
#endif /*EASYCAP_DEBUG*/
|
#endif /*EASYCAP_DEBUG*/
|
||||||
MODULE_PARM_DESC(bars, \
|
MODULE_PARM_DESC(bars, \
|
||||||
"Testcard bars on input signal failure: 0=>no, 1=>yes(default)");
|
"Testcard bars on input signal failure: 0=>no, 1=>yes(default)");
|
||||||
|
@@ -64,6 +64,11 @@ if (NULL == peasycap) {
|
|||||||
SAY("ERROR: peasycap is NULL\n");
|
SAY("ERROR: peasycap is NULL\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
|
||||||
|
SAY("ERROR: bad peasycap\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
much = 0;
|
much = 0;
|
||||||
|
|
||||||
if (peasycap->audio_idle) {
|
if (peasycap->audio_idle) {
|
||||||
@@ -595,6 +600,13 @@ easysnd_open(struct inode *inode, struct file *file)
|
|||||||
struct usb_interface *pusb_interface;
|
struct usb_interface *pusb_interface;
|
||||||
struct easycap *peasycap;
|
struct easycap *peasycap;
|
||||||
int subminor, rc;
|
int subminor, rc;
|
||||||
|
/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
|
||||||
|
#if defined(EASYCAP_IS_VIDEODEV_CLIENT)
|
||||||
|
#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H)
|
||||||
|
struct v4l2_device *pv4l2_device;
|
||||||
|
#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/
|
||||||
|
#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
|
||||||
|
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
|
||||||
|
|
||||||
JOT(4, "begins\n");
|
JOT(4, "begins\n");
|
||||||
|
|
||||||
@@ -612,6 +624,39 @@ if (NULL == peasycap) {
|
|||||||
SAY("ending unsuccessfully\n");
|
SAY("ending unsuccessfully\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
|
||||||
|
#
|
||||||
|
/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
|
||||||
|
#else
|
||||||
|
#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H)
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
* SOME VERSIONS OF THE videodev MODULE OVERWRITE THE DATA WHICH HAS
|
||||||
|
* BEEN WRITTEN BY THE CALL TO usb_set_intfdata() IN easycap_usb_probe(),
|
||||||
|
* REPLACING IT WITH A POINTER TO THE EMBEDDED v4l2_device STRUCTURE.
|
||||||
|
* TO DETECT THIS, THE STRING IN THE easycap.telltale[] BUFFER IS CHECKED.
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
|
||||||
|
pv4l2_device = usb_get_intfdata(pusb_interface);
|
||||||
|
if ((struct v4l2_device *)NULL == pv4l2_device) {
|
||||||
|
SAY("ERROR: pv4l2_device is NULL\n");
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
peasycap = (struct easycap *) \
|
||||||
|
container_of(pv4l2_device, struct easycap, v4l2_device);
|
||||||
|
}
|
||||||
|
#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/
|
||||||
|
#
|
||||||
|
#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
|
||||||
|
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
|
||||||
|
SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap);
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
file->private_data = peasycap;
|
file->private_data = peasycap;
|
||||||
|
|
||||||
@@ -624,7 +669,7 @@ JOM(4, "starting initialization\n");
|
|||||||
|
|
||||||
if ((struct usb_device *)NULL == peasycap->pusb_device) {
|
if ((struct usb_device *)NULL == peasycap->pusb_device) {
|
||||||
SAM("ERROR: peasycap->pusb_device is NULL\n");
|
SAM("ERROR: peasycap->pusb_device is NULL\n");
|
||||||
return -EFAULT;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
JOM(16, "0x%08lX=peasycap->pusb_device\n", (long int)peasycap->pusb_device);
|
JOM(16, "0x%08lX=peasycap->pusb_device\n", (long int)peasycap->pusb_device);
|
||||||
|
|
||||||
@@ -641,7 +686,7 @@ if ((struct usb_device *)NULL == peasycap->pusb_device) {
|
|||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
if ((struct usb_device *)NULL == peasycap->pusb_device) {
|
if ((struct usb_device *)NULL == peasycap->pusb_device) {
|
||||||
SAM("ERROR: peasycap->pusb_device has become NULL\n");
|
SAM("ERROR: peasycap->pusb_device has become NULL\n");
|
||||||
return -EFAULT;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
rc = usb_set_interface(peasycap->pusb_device, peasycap->audio_interface, \
|
rc = usb_set_interface(peasycap->pusb_device, peasycap->audio_interface, \
|
||||||
peasycap->audio_altsetting_on);
|
peasycap->audio_altsetting_on);
|
||||||
@@ -678,6 +723,10 @@ if (NULL == peasycap) {
|
|||||||
SAY("ERROR: peasycap is NULL.\n");
|
SAY("ERROR: peasycap is NULL.\n");
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
|
||||||
|
SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap);
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
if (0 != kill_audio_urbs(peasycap)) {
|
if (0 != kill_audio_urbs(peasycap)) {
|
||||||
SAM("ERROR: kill_audio_urbs() failed\n");
|
SAM("ERROR: kill_audio_urbs() failed\n");
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
@@ -722,6 +771,10 @@ if (NULL == peasycap) {
|
|||||||
SAY("ERROR in easysnd_read(): peasycap is NULL\n");
|
SAY("ERROR in easysnd_read(): peasycap is NULL\n");
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
|
||||||
|
SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap);
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
if (NULL == peasycap->pusb_device) {
|
if (NULL == peasycap->pusb_device) {
|
||||||
SAY("ERROR in easysnd_read(): peasycap->pusb_device is NULL\n");
|
SAY("ERROR in easysnd_read(): peasycap->pusb_device is NULL\n");
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
@@ -753,6 +806,12 @@ if (0 <= kd && DONGLE_MANY > kd) {
|
|||||||
mutex_unlock(&easycap_dongle[kd].mutex_audio);
|
mutex_unlock(&easycap_dongle[kd].mutex_audio);
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
}
|
}
|
||||||
|
if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
|
||||||
|
SAY("ERROR: bad peasycap: 0x%08lX\n", \
|
||||||
|
(unsigned long int) peasycap);
|
||||||
|
mutex_unlock(&easycap_dongle[kd].mutex_audio);
|
||||||
|
return -ERESTARTSYS;
|
||||||
|
}
|
||||||
if (NULL == peasycap->pusb_device) {
|
if (NULL == peasycap->pusb_device) {
|
||||||
SAM("ERROR: peasycap->pusb_device is NULL\n");
|
SAM("ERROR: peasycap->pusb_device is NULL\n");
|
||||||
mutex_unlock(&easycap_dongle[kd].mutex_audio);
|
mutex_unlock(&easycap_dongle[kd].mutex_audio);
|
||||||
|
Reference in New Issue
Block a user