mirror of https://gitee.com/openkylin/linux.git
staging: easycap: add ALSA support
This is necessary because some distributions are disabling OSS entirely. Signed-off-by: Mike Thomas <rmthomas@sciolus.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
b54a28a418
commit
a985591729
|
@ -1,6 +1,6 @@
|
|||
config EASYCAP
|
||||
tristate "EasyCAP USB ID 05e1:0408 support"
|
||||
depends on USB && VIDEO_DEV
|
||||
depends on USB && VIDEO_DEV && SND
|
||||
|
||||
---help---
|
||||
This is an integrated audio/video driver for EasyCAP cards with
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
easycap-objs := easycap_main.o easycap_low.o easycap_sound.o \
|
||||
easycap_ioctl.o easycap_settings.o easycap_testcard.o
|
||||
|
||||
obj-$(CONFIG_EASYCAP) += easycap.o
|
||||
|
||||
easycap-y := easycap_main.o easycap_low.o easycap_sound.o
|
||||
easycap-y += easycap_ioctl.o easycap_settings.o
|
||||
easycap-y += easycap_testcard.o
|
||||
obj-$(CONFIG_EASYCAP) += easycap.o
|
||||
|
||||
ccflags-y := -Wall
|
||||
# Impose all or none of the following:
|
||||
ccflags-y += -DEASYCAP_IS_VIDEODEV_CLIENT
|
||||
ccflags-y += -DEASYCAP_NEEDS_V4L2_DEVICE_H
|
||||
ccflags-y += -DEASYCAP_NEEDS_V4L2_FOPS
|
||||
ccflags-y += -DEASYCAP_NEEDS_UNLOCKED_IOCTL
|
||||
ccflags-y += -DEASYCAP_NEEDS_ALSA
|
||||
ccflags-y += -DEASYCAP_NEEDS_CARD_CREATE
|
||||
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
* EASYCAP_NEEDS_V4L2_DEVICE_H
|
||||
* EASYCAP_NEEDS_V4L2_FOPS
|
||||
* EASYCAP_NEEDS_UNLOCKED_IOCTL
|
||||
* EASYCAP_NEEDS_ALSA
|
||||
* EASYCAP_SILENT
|
||||
*
|
||||
* IF REQUIRED THEY MUST BE EXTERNALLY DEFINED, FOR EXAMPLE AS COMPILER
|
||||
* OPTIONS.
|
||||
|
@ -57,9 +59,9 @@
|
|||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#undef EASYCAP_TESTCARD
|
||||
#if (!defined(EASYCAP_NEEDS_ALSA))
|
||||
#undef EASYCAP_TESTTONE
|
||||
#undef NOREADBACK
|
||||
#undef AUDIOTIME
|
||||
#endif /*EASYCAP_NEEDS_ALSA*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
|
@ -79,6 +81,16 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#if defined(EASYCAP_NEEDS_ALSA)
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/sound.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/pcm_params.h>
|
||||
#include <sound/info.h>
|
||||
#include <sound/initval.h>
|
||||
#include <sound/control.h>
|
||||
#endif /*EASYCAP_NEEDS_ALSA*/
|
||||
/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
|
||||
#if defined(EASYCAP_IS_VIDEODEV_CLIENT)
|
||||
#include <media/v4l2-dev.h>
|
||||
|
@ -112,7 +124,7 @@
|
|||
#define USB_EASYCAP_VENDOR_ID 0x05e1
|
||||
#define USB_EASYCAP_PRODUCT_ID 0x0408
|
||||
|
||||
#define EASYCAP_DRIVER_VERSION "0.8.41"
|
||||
#define EASYCAP_DRIVER_VERSION "0.9.01"
|
||||
#define EASYCAP_DRIVER_DESCRIPTION "easycapdc60"
|
||||
|
||||
#define USB_SKEL_MINOR_BASE 192
|
||||
|
@ -158,7 +170,8 @@
|
|||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define AUDIO_ISOC_BUFFER_MANY 16
|
||||
#define AUDIO_ISOC_ORDER 3
|
||||
#define AUDIO_ISOC_ORDER 1
|
||||
#define AUDIO_ISOC_FRAMESPERDESC 32
|
||||
#define AUDIO_ISOC_BUFFER_SIZE (PAGE_SIZE << AUDIO_ISOC_ORDER)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
|
@ -166,6 +179,7 @@
|
|||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define AUDIO_FRAGMENT_MANY 32
|
||||
#define PAGES_PER_AUDIO_FRAGMENT 4
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* IT IS ESSENTIAL THAT EVEN-NUMBERED STANDARDS ARE 25 FRAMES PER SECOND,
|
||||
|
@ -296,6 +310,7 @@ struct easycap {
|
|||
#define TELLTALE "expectedstring"
|
||||
char telltale[16];
|
||||
int isdongle;
|
||||
int minor;
|
||||
|
||||
/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
|
||||
#if defined(EASYCAP_IS_VIDEODEV_CLIENT)
|
||||
|
@ -328,6 +343,7 @@ int done[FRAME_BUFFER_MANY];
|
|||
|
||||
wait_queue_head_t wq_video;
|
||||
wait_queue_head_t wq_audio;
|
||||
wait_queue_head_t wq_trigger;
|
||||
|
||||
int input;
|
||||
int polled;
|
||||
|
@ -428,6 +444,20 @@ int allocation_video_page;
|
|||
int allocation_video_struct;
|
||||
int registered_video;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* ALSA
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if defined(EASYCAP_NEEDS_ALSA)
|
||||
struct snd_pcm_hardware alsa_hardware;
|
||||
struct snd_card *psnd_card;
|
||||
struct snd_pcm *psnd_pcm;
|
||||
struct snd_pcm_substream *psubstream;
|
||||
int dma_fill;
|
||||
int dma_next;
|
||||
int dma_read;
|
||||
#endif /*EASYCAP_NEEDS_ALSA*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* SOUND PROPERTIES
|
||||
*/
|
||||
|
@ -455,10 +485,10 @@ struct list_head *purb_audio_head;
|
|||
* BUFFER INDICATORS
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int audio_fill; /* Audio buffer being filled by easysnd_complete(). */
|
||||
/* Bumped only by easysnd_complete(). */
|
||||
int audio_read; /* Audio buffer page being read by easysnd_read(). */
|
||||
/* Set by easysnd_read() to trail audio_fill by */
|
||||
int audio_fill; /* Audio buffer being filled by easycap_complete(). */
|
||||
/* Bumped only by easycap_complete(). */
|
||||
int audio_read; /* Audio buffer page being read by easycap_read(). */
|
||||
/* Set by easycap_read() to trail audio_fill by */
|
||||
/* one fragment. */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
|
@ -532,19 +562,39 @@ int adjust_volume(struct easycap *, int);
|
|||
* AUDIO FUNCTION PROTOTYPES
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void easysnd_complete(struct urb *);
|
||||
ssize_t easysnd_read(struct file *, char __user *, size_t, loff_t *);
|
||||
int easysnd_open(struct inode *, struct file *);
|
||||
int easysnd_release(struct inode *, struct file *);
|
||||
long easysnd_ioctl_noinode(struct file *, unsigned int, \
|
||||
#if defined(EASYCAP_NEEDS_ALSA)
|
||||
int easycap_alsa_probe(struct easycap *);
|
||||
|
||||
void easycap_alsa_complete(struct urb *);
|
||||
int easycap_alsa_open(struct snd_pcm_substream *);
|
||||
int easycap_alsa_close(struct snd_pcm_substream *);
|
||||
int easycap_alsa_hw_params(struct snd_pcm_substream *, \
|
||||
struct snd_pcm_hw_params *);
|
||||
int easycap_alsa_vmalloc(struct snd_pcm_substream *, size_t);
|
||||
int easycap_alsa_hw_free(struct snd_pcm_substream *);
|
||||
int easycap_alsa_prepare(struct snd_pcm_substream *);
|
||||
int easycap_alsa_ack(struct snd_pcm_substream *);
|
||||
int easycap_alsa_trigger(struct snd_pcm_substream *, int);
|
||||
snd_pcm_uframes_t \
|
||||
easycap_alsa_pointer(struct snd_pcm_substream *);
|
||||
struct page *easycap_alsa_page(struct snd_pcm_substream *, unsigned long);
|
||||
|
||||
#else
|
||||
void easyoss_complete(struct urb *);
|
||||
ssize_t easyoss_read(struct file *, char __user *, size_t, loff_t *);
|
||||
int easyoss_open(struct inode *, struct file *);
|
||||
int easyoss_release(struct inode *, struct file *);
|
||||
long easyoss_ioctl_noinode(struct file *, unsigned int, \
|
||||
unsigned long);
|
||||
int easysnd_ioctl(struct inode *, struct file *, unsigned int, \
|
||||
int easyoss_ioctl(struct inode *, struct file *, unsigned int, \
|
||||
unsigned long);
|
||||
unsigned int easysnd_poll(struct file *, poll_table *);
|
||||
void easysnd_delete(struct kref *);
|
||||
unsigned int easyoss_poll(struct file *, poll_table *);
|
||||
void easyoss_delete(struct kref *);
|
||||
#endif /*EASYCAP_NEEDS_ALSA*/
|
||||
int easycap_sound_setup(struct easycap *);
|
||||
int submit_audio_urbs(struct easycap *);
|
||||
int kill_audio_urbs(struct easycap *);
|
||||
void easysnd_testtone(struct easycap *, int);
|
||||
void easyoss_testtone(struct easycap *, int);
|
||||
int audio_setup(struct easycap *);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
|
|
|
@ -27,8 +27,6 @@
|
|||
|
||||
#include <linux/smp_lock.h>
|
||||
#include "easycap.h"
|
||||
#include "easycap_debug.h"
|
||||
#include "easycap_standard.h"
|
||||
#include "easycap_ioctl.h"
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
@ -910,7 +908,7 @@ return -ENOENT;
|
|||
* peasycap->audio_interface, \
|
||||
* peasycap->audio_altsetting_off);
|
||||
* HOWEVER, AFTER THIS COMMAND IS ISSUED ALL SUBSEQUENT URBS RECEIVE STATUS
|
||||
* -ESHUTDOWN. THE HANDLER ROUTINE easysnd_complete() DECLINES TO RESUBMIT
|
||||
* -ESHUTDOWN. THE HANDLER ROUTINE easyxxx_complete() DECLINES TO RESUBMIT
|
||||
* THE URB AND THE PIPELINE COLLAPSES IRRETRIEVABLY. BEWARE.
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -991,11 +989,12 @@ if (NULL == p) {
|
|||
}
|
||||
kd = isdongle(peasycap);
|
||||
if (0 <= kd && DONGLE_MANY > kd) {
|
||||
if (mutex_lock_interruptible(&easycap_dongle[kd].mutex_video)) {
|
||||
SAY("ERROR: cannot lock easycap_dongle[%i].mutex_video\n", kd);
|
||||
if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_video)) {
|
||||
SAY("ERROR: cannot lock " \
|
||||
"easycapdc60_dongle[%i].mutex_video\n", kd);
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
JOM(4, "locked easycap_dongle[%i].mutex_video\n", kd);
|
||||
JOM(4, "locked easycapdc60_dongle[%i].mutex_video\n", kd);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER peasycap,
|
||||
|
@ -1007,24 +1006,24 @@ if (0 <= kd && DONGLE_MANY > kd) {
|
|||
return -ERESTARTSYS;
|
||||
if (NULL == file) {
|
||||
SAY("ERROR: file is NULL\n");
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
peasycap = file->private_data;
|
||||
if (NULL == peasycap) {
|
||||
SAY("ERROR: peasycap is NULL\n");
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
|
||||
SAY("ERROR: bad peasycap\n");
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
p = peasycap->pusb_device;
|
||||
if (NULL == peasycap->pusb_device) {
|
||||
SAM("ERROR: peasycap->pusb_device is NULL\n");
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
} else {
|
||||
|
@ -1048,7 +1047,7 @@ case VIDIOC_QUERYCAP: {
|
|||
|
||||
if (16 <= strlen(EASYCAP_DRIVER_VERSION)) {
|
||||
SAM("ERROR: bad driver version string\n");
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EINVAL;
|
||||
}
|
||||
strcpy(&version[0], EASYCAP_DRIVER_VERSION);
|
||||
|
@ -1066,7 +1065,8 @@ case VIDIOC_QUERYCAP: {
|
|||
if (0 != rc) {
|
||||
SAM("ERROR: %i=strict_strtol(%s,.,,)\n", \
|
||||
rc, p1);
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].\
|
||||
mutex_video);
|
||||
return -EINVAL;
|
||||
}
|
||||
k[i] = (int)lng;
|
||||
|
@ -1097,7 +1097,7 @@ case VIDIOC_QUERYCAP: {
|
|||
}
|
||||
if (0 != copy_to_user((void __user *)arg, &v4l2_capability, \
|
||||
sizeof(struct v4l2_capability))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
break;
|
||||
|
@ -1111,7 +1111,7 @@ case VIDIOC_ENUMINPUT: {
|
|||
|
||||
if (0 != copy_from_user(&v4l2_input, (void __user *)arg, \
|
||||
sizeof(struct v4l2_input))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
|
@ -1193,14 +1193,14 @@ case VIDIOC_ENUMINPUT: {
|
|||
}
|
||||
default: {
|
||||
JOM(8, "%i=index: exhausts inputs\n", index);
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 != copy_to_user((void __user *)arg, &v4l2_input, \
|
||||
sizeof(struct v4l2_input))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
break;
|
||||
|
@ -1213,7 +1213,7 @@ case VIDIOC_G_INPUT: {
|
|||
index = (__u32)peasycap->input;
|
||||
JOM(8, "user is told: %i\n", index);
|
||||
if (0 != copy_to_user((void __user *)arg, &index, sizeof(__u32))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
break;
|
||||
|
@ -1227,7 +1227,7 @@ case VIDIOC_S_INPUT:
|
|||
JOM(8, "VIDIOC_S_INPUT\n");
|
||||
|
||||
if (0 != copy_from_user(&index, (void __user *)arg, sizeof(__u32))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
|
@ -1240,7 +1240,7 @@ case VIDIOC_S_INPUT:
|
|||
|
||||
if ((0 > index) || (INPUT_MANY <= index)) {
|
||||
JOM(8, "ERROR: bad requested input: %i\n", index);
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -1249,7 +1249,7 @@ case VIDIOC_S_INPUT:
|
|||
JOM(8, "newinput(.,%i) OK\n", (int)index);
|
||||
} else {
|
||||
SAM("ERROR: newinput(.,%i) returned %i\n", (int)index, rc);
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
break;
|
||||
|
@ -1257,7 +1257,7 @@ case VIDIOC_S_INPUT:
|
|||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
case VIDIOC_ENUMAUDIO: {
|
||||
JOM(8, "VIDIOC_ENUMAUDIO\n");
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EINVAL;
|
||||
}
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
@ -1268,12 +1268,12 @@ case VIDIOC_ENUMAUDOUT: {
|
|||
|
||||
if (0 != copy_from_user(&v4l2_audioout, (void __user *)arg, \
|
||||
sizeof(struct v4l2_audioout))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (0 != v4l2_audioout.index) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EINVAL;
|
||||
}
|
||||
memset(&v4l2_audioout, 0, sizeof(struct v4l2_audioout));
|
||||
|
@ -1282,7 +1282,7 @@ case VIDIOC_ENUMAUDOUT: {
|
|||
|
||||
if (0 != copy_to_user((void __user *)arg, &v4l2_audioout, \
|
||||
sizeof(struct v4l2_audioout))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
break;
|
||||
|
@ -1296,7 +1296,7 @@ case VIDIOC_QUERYCTRL: {
|
|||
|
||||
if (0 != copy_from_user(&v4l2_queryctrl, (void __user *)arg, \
|
||||
sizeof(struct v4l2_queryctrl))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
|
@ -1313,12 +1313,12 @@ case VIDIOC_QUERYCTRL: {
|
|||
}
|
||||
if (0xFFFFFFFF == easycap_control[i1].id) {
|
||||
JOM(8, "%i=index: exhausts controls\n", i1);
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (0 != copy_to_user((void __user *)arg, &v4l2_queryctrl, \
|
||||
sizeof(struct v4l2_queryctrl))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
break;
|
||||
|
@ -1326,7 +1326,7 @@ case VIDIOC_QUERYCTRL: {
|
|||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
case VIDIOC_QUERYMENU: {
|
||||
JOM(8, "VIDIOC_QUERYMENU unsupported\n");
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EINVAL;
|
||||
}
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
@ -1337,13 +1337,13 @@ case VIDIOC_G_CTRL: {
|
|||
pv4l2_control = kzalloc(sizeof(struct v4l2_control), GFP_KERNEL);
|
||||
if (!pv4l2_control) {
|
||||
SAM("ERROR: out of memory\n");
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (0 != copy_from_user(pv4l2_control, (void __user *)arg, \
|
||||
sizeof(struct v4l2_control))) {
|
||||
kfree(pv4l2_control);
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
|
@ -1385,14 +1385,14 @@ case VIDIOC_G_CTRL: {
|
|||
SAM("ERROR: unknown V4L2 control: 0x%08X=id\n", \
|
||||
pv4l2_control->id);
|
||||
kfree(pv4l2_control);
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
if (0 != copy_to_user((void __user *)arg, pv4l2_control, \
|
||||
sizeof(struct v4l2_control))) {
|
||||
kfree(pv4l2_control);
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
kfree(pv4l2_control);
|
||||
|
@ -1412,7 +1412,7 @@ case VIDIOC_S_CTRL:
|
|||
|
||||
if (0 != copy_from_user(&v4l2_control, (void __user *)arg, \
|
||||
sizeof(struct v4l2_control))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
|
@ -1463,7 +1463,7 @@ case VIDIOC_S_CTRL:
|
|||
default: {
|
||||
SAM("ERROR: unknown V4L2 control: 0x%08X=id\n", \
|
||||
v4l2_control.id);
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
@ -1472,7 +1472,7 @@ case VIDIOC_S_CTRL:
|
|||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
case VIDIOC_S_EXT_CTRLS: {
|
||||
JOM(8, "VIDIOC_S_EXT_CTRLS unsupported\n");
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EINVAL;
|
||||
}
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
@ -1484,7 +1484,7 @@ case VIDIOC_ENUM_FMT: {
|
|||
|
||||
if (0 != copy_from_user(&v4l2_fmtdesc, (void __user *)arg, \
|
||||
sizeof(struct v4l2_fmtdesc))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
|
@ -1539,13 +1539,13 @@ case VIDIOC_ENUM_FMT: {
|
|||
}
|
||||
default: {
|
||||
JOM(8, "%i=index: exhausts formats\n", index);
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
if (0 != copy_to_user((void __user *)arg, &v4l2_fmtdesc, \
|
||||
sizeof(struct v4l2_fmtdesc))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
break;
|
||||
|
@ -1564,7 +1564,7 @@ case VIDIOC_ENUM_FRAMESIZES: {
|
|||
|
||||
if (0 != copy_from_user(&v4l2_frmsizeenum, (void __user *)arg, \
|
||||
sizeof(struct v4l2_frmsizeenum))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
|
@ -1616,7 +1616,7 @@ case VIDIOC_ENUM_FRAMESIZES: {
|
|||
}
|
||||
default: {
|
||||
JOM(8, "%i=index: exhausts framesizes\n", index);
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
@ -1674,14 +1674,14 @@ case VIDIOC_ENUM_FRAMESIZES: {
|
|||
}
|
||||
default: {
|
||||
JOM(8, "%i=index: exhausts framesizes\n", index);
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (0 != copy_to_user((void __user *)arg, &v4l2_frmsizeenum, \
|
||||
sizeof(struct v4l2_frmsizeenum))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
break;
|
||||
|
@ -1710,7 +1710,7 @@ case VIDIOC_ENUM_FRAMEINTERVALS: {
|
|||
|
||||
if (0 != copy_from_user(&v4l2_frmivalenum, (void __user *)arg, \
|
||||
sizeof(struct v4l2_frmivalenum))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
|
@ -1737,13 +1737,13 @@ case VIDIOC_ENUM_FRAMEINTERVALS: {
|
|||
}
|
||||
default: {
|
||||
JOM(8, "%i=index: exhausts frameintervals\n", index);
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
if (0 != copy_to_user((void __user *)arg, &v4l2_frmivalenum, \
|
||||
sizeof(struct v4l2_frmivalenum))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
break;
|
||||
|
@ -1757,28 +1757,28 @@ case VIDIOC_G_FMT: {
|
|||
pv4l2_format = kzalloc(sizeof(struct v4l2_format), GFP_KERNEL);
|
||||
if (!pv4l2_format) {
|
||||
SAM("ERROR: out of memory\n");
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -ENOMEM;
|
||||
}
|
||||
pv4l2_pix_format = kzalloc(sizeof(struct v4l2_pix_format), GFP_KERNEL);
|
||||
if (!pv4l2_pix_format) {
|
||||
SAM("ERROR: out of memory\n");
|
||||
kfree(pv4l2_format);
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (0 != copy_from_user(pv4l2_format, (void __user *)arg, \
|
||||
sizeof(struct v4l2_format))) {
|
||||
kfree(pv4l2_format);
|
||||
kfree(pv4l2_pix_format);
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (pv4l2_format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
|
||||
kfree(pv4l2_format);
|
||||
kfree(pv4l2_pix_format);
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -1794,7 +1794,7 @@ case VIDIOC_G_FMT: {
|
|||
sizeof(struct v4l2_format))) {
|
||||
kfree(pv4l2_format);
|
||||
kfree(pv4l2_pix_format);
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
kfree(pv4l2_format);
|
||||
|
@ -1819,7 +1819,7 @@ case VIDIOC_S_FMT: {
|
|||
|
||||
if (0 != copy_from_user(&v4l2_format, (void __user *)arg, \
|
||||
sizeof(struct v4l2_format))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
|
@ -1831,11 +1831,11 @@ case VIDIOC_S_FMT: {
|
|||
try);
|
||||
if (0 > best_format) {
|
||||
if (-EBUSY == best_format) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EBUSY;
|
||||
}
|
||||
JOM(8, "WARNING: adjust_format() returned %i\n", best_format);
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -ENOENT;
|
||||
}
|
||||
/*...........................................................................*/
|
||||
|
@ -1848,7 +1848,7 @@ case VIDIOC_S_FMT: {
|
|||
|
||||
if (0 != copy_to_user((void __user *)arg, &v4l2_format, \
|
||||
sizeof(struct v4l2_format))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
break;
|
||||
|
@ -1861,7 +1861,7 @@ case VIDIOC_CROPCAP: {
|
|||
|
||||
if (0 != copy_from_user(&v4l2_cropcap, (void __user *)arg, \
|
||||
sizeof(struct v4l2_cropcap))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
|
@ -1885,7 +1885,7 @@ case VIDIOC_CROPCAP: {
|
|||
|
||||
if (0 != copy_to_user((void __user *)arg, &v4l2_cropcap, \
|
||||
sizeof(struct v4l2_cropcap))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
break;
|
||||
|
@ -1894,14 +1894,14 @@ case VIDIOC_CROPCAP: {
|
|||
case VIDIOC_G_CROP:
|
||||
case VIDIOC_S_CROP: {
|
||||
JOM(8, "VIDIOC_G_CROP|VIDIOC_S_CROP unsupported\n");
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EINVAL;
|
||||
}
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
case VIDIOC_QUERYSTD: {
|
||||
JOM(8, "VIDIOC_QUERYSTD: " \
|
||||
"EasyCAP is incapable of detecting standard\n");
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
@ -1923,7 +1923,7 @@ case VIDIOC_ENUMSTD: {
|
|||
|
||||
if (0 != copy_from_user(&v4l2_standard, (void __user *)arg, \
|
||||
sizeof(struct v4l2_standard))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
index = v4l2_standard.index;
|
||||
|
@ -1945,7 +1945,7 @@ case VIDIOC_ENUMSTD: {
|
|||
}
|
||||
if (0xFFFF == peasycap_standard->mask) {
|
||||
JOM(8, "%i=index: exhausts standards\n", index);
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EINVAL;
|
||||
}
|
||||
JOM(8, "%i=index: %s\n", index, \
|
||||
|
@ -1957,7 +1957,7 @@ case VIDIOC_ENUMSTD: {
|
|||
|
||||
if (0 != copy_to_user((void __user *)arg, &v4l2_standard, \
|
||||
sizeof(struct v4l2_standard))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
break;
|
||||
|
@ -1972,13 +1972,13 @@ case VIDIOC_G_STD: {
|
|||
if (0 > peasycap->standard_offset) {
|
||||
JOM(8, "%i=peasycap->standard_offset\n", \
|
||||
peasycap->standard_offset);
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (0 != copy_from_user(&std_id, (void __user *)arg, \
|
||||
sizeof(v4l2_std_id))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
|
@ -1990,7 +1990,7 @@ case VIDIOC_G_STD: {
|
|||
|
||||
if (0 != copy_to_user((void __user *)arg, &std_id, \
|
||||
sizeof(v4l2_std_id))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
break;
|
||||
|
@ -2004,7 +2004,7 @@ case VIDIOC_S_STD: {
|
|||
|
||||
if (0 != copy_from_user(&std_id, (void __user *)arg, \
|
||||
sizeof(v4l2_std_id))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
|
@ -2015,7 +2015,7 @@ case VIDIOC_S_STD: {
|
|||
rc = adjust_standard(peasycap, std_id);
|
||||
if (0 > rc) {
|
||||
JOM(8, "WARNING: adjust_standard() returned %i\n", rc);
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -ENOENT;
|
||||
}
|
||||
break;
|
||||
|
@ -2029,16 +2029,16 @@ case VIDIOC_REQBUFS: {
|
|||
|
||||
if (0 != copy_from_user(&v4l2_requestbuffers, (void __user *)arg, \
|
||||
sizeof(struct v4l2_requestbuffers))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (v4l2_requestbuffers.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (v4l2_requestbuffers.memory != V4L2_MEMORY_MMAP) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EINVAL;
|
||||
}
|
||||
nbuffers = v4l2_requestbuffers.count;
|
||||
|
@ -2059,7 +2059,7 @@ case VIDIOC_REQBUFS: {
|
|||
|
||||
if (0 != copy_to_user((void __user *)arg, &v4l2_requestbuffers, \
|
||||
sizeof(struct v4l2_requestbuffers))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
break;
|
||||
|
@ -2074,18 +2074,18 @@ case VIDIOC_QUERYBUF: {
|
|||
if (peasycap->video_eof) {
|
||||
JOM(8, "returning -EIO because %i=video_eof\n", \
|
||||
peasycap->video_eof);
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \
|
||||
sizeof(struct v4l2_buffer))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EINVAL;
|
||||
}
|
||||
index = v4l2_buffer.index;
|
||||
|
@ -2117,7 +2117,7 @@ case VIDIOC_QUERYBUF: {
|
|||
|
||||
if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \
|
||||
sizeof(struct v4l2_buffer))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
break;
|
||||
|
@ -2130,21 +2130,21 @@ case VIDIOC_QBUF: {
|
|||
|
||||
if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \
|
||||
sizeof(struct v4l2_buffer))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (v4l2_buffer.memory != V4L2_MEMORY_MMAP) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (v4l2_buffer.index < 0 || \
|
||||
(v4l2_buffer.index >= peasycap->frame_buffer_many)) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EINVAL;
|
||||
}
|
||||
v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED;
|
||||
|
@ -2154,7 +2154,7 @@ case VIDIOC_QBUF: {
|
|||
|
||||
if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \
|
||||
sizeof(struct v4l2_buffer))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
|
@ -2187,18 +2187,18 @@ case VIDIOC_DQBUF:
|
|||
JOM(8, "returning -EIO because " \
|
||||
"%i=video_idle %i=video_eof\n", \
|
||||
peasycap->video_idle, peasycap->video_eof);
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \
|
||||
sizeof(struct v4l2_buffer))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -2222,7 +2222,7 @@ case VIDIOC_DQBUF:
|
|||
|
||||
if (!peasycap->video_isoc_streaming) {
|
||||
JOM(16, "returning -EIO because video urbs not streaming\n");
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EIO;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -2239,18 +2239,19 @@ case VIDIOC_DQBUF:
|
|||
if (-EIO == rcdq) {
|
||||
JOM(8, "returning -EIO because " \
|
||||
"dqbuf() returned -EIO\n");
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].\
|
||||
mutex_video);
|
||||
return -EIO;
|
||||
}
|
||||
} while (0 != rcdq);
|
||||
} else {
|
||||
if (peasycap->video_eof) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
if (V4L2_BUF_FLAG_DONE != peasycap->done[peasycap->frame_read]) {
|
||||
SAM("ERROR: V4L2_BUF_FLAG_DONE != 0x%08X\n", \
|
||||
JOM(8, "V4L2_BUF_FLAG_DONE != 0x%08X\n", \
|
||||
peasycap->done[peasycap->frame_read]);
|
||||
}
|
||||
peasycap->polled = 0;
|
||||
|
@ -2337,7 +2338,7 @@ case VIDIOC_DQBUF:
|
|||
|
||||
if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \
|
||||
sizeof(struct v4l2_buffer))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
|
@ -2370,7 +2371,7 @@ case VIDIOC_STREAMON: {
|
|||
peasycap->merit[i] = 0;
|
||||
if ((struct usb_device *)NULL == peasycap->pusb_device) {
|
||||
SAM("ERROR: peasycap->pusb_device is NULL\n");
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
submit_video_urbs(peasycap);
|
||||
|
@ -2386,7 +2387,7 @@ case VIDIOC_STREAMOFF: {
|
|||
|
||||
if ((struct usb_device *)NULL == peasycap->pusb_device) {
|
||||
SAM("ERROR: peasycap->pusb_device is NULL\n");
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
|
@ -2400,7 +2401,12 @@ case VIDIOC_STREAMOFF: {
|
|||
/*---------------------------------------------------------------------------*/
|
||||
JOM(8, "calling wake_up on wq_video and wq_audio\n");
|
||||
wake_up_interruptible(&(peasycap->wq_video));
|
||||
#if defined(EASYCAP_NEEDS_ALSA)
|
||||
if (NULL != peasycap->psubstream)
|
||||
snd_pcm_period_elapsed(peasycap->psubstream);
|
||||
#else
|
||||
wake_up_interruptible(&(peasycap->wq_audio));
|
||||
#endif /*EASYCAP_NEEDS_ALSA*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
break;
|
||||
}
|
||||
|
@ -2412,19 +2418,19 @@ case VIDIOC_G_PARM: {
|
|||
pv4l2_streamparm = kzalloc(sizeof(struct v4l2_streamparm), GFP_KERNEL);
|
||||
if (!pv4l2_streamparm) {
|
||||
SAM("ERROR: out of memory\n");
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (0 != copy_from_user(pv4l2_streamparm, (void __user *)arg, \
|
||||
sizeof(struct v4l2_streamparm))) {
|
||||
kfree(pv4l2_streamparm);
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (pv4l2_streamparm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
|
||||
kfree(pv4l2_streamparm);
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EINVAL;
|
||||
}
|
||||
pv4l2_streamparm->parm.capture.capability = 0;
|
||||
|
@ -2450,7 +2456,7 @@ case VIDIOC_G_PARM: {
|
|||
if (0 != copy_to_user((void __user *)arg, pv4l2_streamparm, \
|
||||
sizeof(struct v4l2_streamparm))) {
|
||||
kfree(pv4l2_streamparm);
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EFAULT;
|
||||
}
|
||||
kfree(pv4l2_streamparm);
|
||||
|
@ -2459,25 +2465,25 @@ case VIDIOC_G_PARM: {
|
|||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
case VIDIOC_S_PARM: {
|
||||
JOM(8, "VIDIOC_S_PARM unsupported\n");
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EINVAL;
|
||||
}
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
case VIDIOC_G_AUDIO: {
|
||||
JOM(8, "VIDIOC_G_AUDIO unsupported\n");
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EINVAL;
|
||||
}
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
case VIDIOC_S_AUDIO: {
|
||||
JOM(8, "VIDIOC_S_AUDIO unsupported\n");
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EINVAL;
|
||||
}
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
case VIDIOC_S_TUNER: {
|
||||
JOM(8, "VIDIOC_S_TUNER unsupported\n");
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EINVAL;
|
||||
}
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
@ -2485,45 +2491,46 @@ case VIDIOC_G_FBUF:
|
|||
case VIDIOC_S_FBUF:
|
||||
case VIDIOC_OVERLAY: {
|
||||
JOM(8, "VIDIOC_G_FBUF|VIDIOC_S_FBUF|VIDIOC_OVERLAY unsupported\n");
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EINVAL;
|
||||
}
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
case VIDIOC_G_TUNER: {
|
||||
JOM(8, "VIDIOC_G_TUNER unsupported\n");
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EINVAL;
|
||||
}
|
||||
case VIDIOC_G_FREQUENCY:
|
||||
case VIDIOC_S_FREQUENCY: {
|
||||
JOM(8, "VIDIOC_G_FREQUENCY|VIDIOC_S_FREQUENCY unsupported\n");
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -EINVAL;
|
||||
}
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
default: {
|
||||
JOM(8, "ERROR: unrecognized V4L2 IOCTL command: 0x%08X\n", cmd);
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -ENOIOCTLCMD;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
JOM(4, "unlocked easycap_dongle[%i].mutex_video\n", kd);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
JOM(4, "unlocked easycapdc60_dongle[%i].mutex_video\n", kd);
|
||||
return 0;
|
||||
}
|
||||
/*****************************************************************************/
|
||||
#if !defined(EASYCAP_NEEDS_ALSA)
|
||||
/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
|
||||
#if ((defined(EASYCAP_IS_VIDEODEV_CLIENT)) || \
|
||||
(defined(EASYCAP_NEEDS_UNLOCKED_IOCTL)))
|
||||
long
|
||||
easysnd_ioctl_noinode(struct file *file, unsigned int cmd, unsigned long arg) {
|
||||
return (long)easysnd_ioctl((struct inode *)NULL, file, cmd, arg);
|
||||
easyoss_ioctl_noinode(struct file *file, unsigned int cmd, unsigned long arg) {
|
||||
return (long)easyoss_ioctl((struct inode *)NULL, file, cmd, arg);
|
||||
}
|
||||
#endif /*EASYCAP_IS_VIDEODEV_CLIENT||EASYCAP_NEEDS_UNLOCKED_IOCTL*/
|
||||
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
easysnd_ioctl(struct inode *inode, struct file *file,
|
||||
easyoss_ioctl(struct inode *inode, struct file *file,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct easycap *peasycap;
|
||||
|
@ -2550,11 +2557,12 @@ if (NULL == p) {
|
|||
}
|
||||
kd = isdongle(peasycap);
|
||||
if (0 <= kd && DONGLE_MANY > kd) {
|
||||
if (mutex_lock_interruptible(&easycap_dongle[kd].mutex_audio)) {
|
||||
SAY("ERROR: cannot lock easycap_dongle[%i].mutex_audio\n", kd);
|
||||
if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_audio)) {
|
||||
SAY("ERROR: cannot lock "
|
||||
"easycapdc60_dongle[%i].mutex_audio\n", kd);
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
JOM(4, "locked easycap_dongle[%i].mutex_audio\n", kd);
|
||||
JOM(4, "locked easycapdc60_dongle[%i].mutex_audio\n", kd);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER peasycap,
|
||||
|
@ -2566,24 +2574,24 @@ if (0 <= kd && DONGLE_MANY > kd) {
|
|||
return -ERESTARTSYS;
|
||||
if (NULL == file) {
|
||||
SAY("ERROR: file is NULL\n");
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_audio);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
peasycap = file->private_data;
|
||||
if (NULL == peasycap) {
|
||||
SAY("ERROR: peasycap is NULL\n");
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_audio);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
|
||||
SAY("ERROR: bad peasycap\n");
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_audio);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
|
||||
return -EFAULT;
|
||||
}
|
||||
p = peasycap->pusb_device;
|
||||
if (NULL == peasycap->pusb_device) {
|
||||
SAM("ERROR: peasycap->pusb_device is NULL\n");
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_audio);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
} else {
|
||||
|
@ -2614,7 +2622,7 @@ case SNDCTL_DSP_GETCAPS: {
|
|||
#endif /*UPSAMPLE*/
|
||||
|
||||
if (0 != copy_to_user((void __user *)arg, &caps, sizeof(int))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_audio);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
|
||||
return -EFAULT;
|
||||
}
|
||||
break;
|
||||
|
@ -2636,7 +2644,7 @@ case SNDCTL_DSP_GETFMTS: {
|
|||
#endif /*UPSAMPLE*/
|
||||
|
||||
if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_audio);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
|
||||
return -EFAULT;
|
||||
}
|
||||
break;
|
||||
|
@ -2645,7 +2653,7 @@ case SNDCTL_DSP_SETFMT: {
|
|||
int incoming, outgoing;
|
||||
JOM(8, "SNDCTL_DSP_SETFMT\n");
|
||||
if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_audio);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
|
||||
return -EFAULT;
|
||||
}
|
||||
JOM(8, "........... %i=incoming\n", incoming);
|
||||
|
@ -2668,10 +2676,10 @@ case SNDCTL_DSP_SETFMT: {
|
|||
JOM(8, " cf. %i=AFMT_U8\n", AFMT_U8);
|
||||
if (0 != copy_to_user((void __user *)arg, &outgoing, \
|
||||
sizeof(int))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_audio);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
|
||||
return -EFAULT;
|
||||
}
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_audio);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
|
||||
return -EINVAL ;
|
||||
}
|
||||
break;
|
||||
|
@ -2680,7 +2688,7 @@ case SNDCTL_DSP_STEREO: {
|
|||
int incoming;
|
||||
JOM(8, "SNDCTL_DSP_STEREO\n");
|
||||
if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_audio);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
|
||||
return -EFAULT;
|
||||
}
|
||||
JOM(8, "........... %i=incoming\n", incoming);
|
||||
|
@ -2698,7 +2706,7 @@ case SNDCTL_DSP_STEREO: {
|
|||
#endif /*UPSAMPLE*/
|
||||
|
||||
if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_audio);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
|
||||
return -EFAULT;
|
||||
}
|
||||
break;
|
||||
|
@ -2707,7 +2715,7 @@ case SNDCTL_DSP_SPEED: {
|
|||
int incoming;
|
||||
JOM(8, "SNDCTL_DSP_SPEED\n");
|
||||
if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_audio);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
|
||||
return -EFAULT;
|
||||
}
|
||||
JOM(8, "........... %i=incoming\n", incoming);
|
||||
|
@ -2725,7 +2733,7 @@ case SNDCTL_DSP_SPEED: {
|
|||
#endif /*UPSAMPLE*/
|
||||
|
||||
if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_audio);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
|
||||
return -EFAULT;
|
||||
}
|
||||
break;
|
||||
|
@ -2734,14 +2742,14 @@ case SNDCTL_DSP_GETTRIGGER: {
|
|||
int incoming;
|
||||
JOM(8, "SNDCTL_DSP_GETTRIGGER\n");
|
||||
if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_audio);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
|
||||
return -EFAULT;
|
||||
}
|
||||
JOM(8, "........... %i=incoming\n", incoming);
|
||||
|
||||
incoming = PCM_ENABLE_INPUT;
|
||||
if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_audio);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
|
||||
return -EFAULT;
|
||||
}
|
||||
break;
|
||||
|
@ -2750,7 +2758,7 @@ case SNDCTL_DSP_SETTRIGGER: {
|
|||
int incoming;
|
||||
JOM(8, "SNDCTL_DSP_SETTRIGGER\n");
|
||||
if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_audio);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
|
||||
return -EFAULT;
|
||||
}
|
||||
JOM(8, "........... %i=incoming\n", incoming);
|
||||
|
@ -2767,13 +2775,13 @@ case SNDCTL_DSP_GETBLKSIZE: {
|
|||
int incoming;
|
||||
JOM(8, "SNDCTL_DSP_GETBLKSIZE\n");
|
||||
if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_audio);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
|
||||
return -EFAULT;
|
||||
}
|
||||
JOM(8, "........... %i=incoming\n", incoming);
|
||||
incoming = peasycap->audio_bytes_per_fragment;
|
||||
if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_audio);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
|
||||
return -EFAULT;
|
||||
}
|
||||
break;
|
||||
|
@ -2790,7 +2798,7 @@ case SNDCTL_DSP_GETISPACE: {
|
|||
|
||||
if (0 != copy_to_user((void __user *)arg, &audio_buf_info, \
|
||||
sizeof(int))) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_audio);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
|
||||
return -EFAULT;
|
||||
}
|
||||
break;
|
||||
|
@ -2802,18 +2810,18 @@ case 0x00005404:
|
|||
case 0x00005405:
|
||||
case 0x00005406: {
|
||||
JOM(8, "SNDCTL_TMR_...: 0x%08X unsupported\n", cmd);
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_audio);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
|
||||
return -ENOIOCTLCMD;
|
||||
}
|
||||
default: {
|
||||
JOM(8, "ERROR: unrecognized DSP IOCTL command: 0x%08X\n", cmd);
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_audio);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
|
||||
return -ENOIOCTLCMD;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_audio);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
|
||||
return 0;
|
||||
}
|
||||
#endif /*EASYCAP_NEEDS_ALSA*/
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
|
|
@ -24,5 +24,14 @@
|
|||
*
|
||||
*/
|
||||
/*****************************************************************************/
|
||||
#if !defined(EASYCAP_IOCTL_H)
|
||||
#define EASYCAP_IOCTL_H
|
||||
|
||||
extern int easycap_debug;
|
||||
extern int easycap_gain;
|
||||
extern struct easycap_dongle easycapdc60_dongle[];
|
||||
extern struct easycap_standard easycap_standard[];
|
||||
extern struct easycap_format easycap_format[];
|
||||
extern struct v4l2_queryctrl easycap_control[];
|
||||
|
||||
#endif /*EASYCAP_IOCTL_H*/
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
/****************************************************************************/
|
||||
|
||||
#include "easycap.h"
|
||||
#include "easycap_debug.h"
|
||||
#include "easycap_low.h"
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
const struct stk1160config { int reg; int set; } stk1160configPAL[256] = {
|
||||
|
@ -1052,9 +1052,18 @@ rc = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), \
|
|||
(int)50000);
|
||||
|
||||
JOT(8, "0x%02X=buffer\n", *((__u8 *) &buffer[0]));
|
||||
if (rc != (int)length)
|
||||
SAY("ERROR: usb_control_msg returned %i\n", rc);
|
||||
|
||||
if (rc != (int)length) {
|
||||
switch (rc) {
|
||||
case -EPIPE: {
|
||||
SAY("usb_control_msg returned -EPIPE\n");
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
SAY("ERROR: usb_control_msg returned %i\n", rc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/*
|
||||
* REGISTER 500: SETTING VALUE TO 0x0094 RESETS AUDIO CONFIGURATION ???
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
* *
|
||||
* easycap_debug.h *
|
||||
* easycap_low.h *
|
||||
* *
|
||||
*****************************************************************************/
|
||||
/*
|
||||
|
@ -24,6 +24,11 @@
|
|||
*
|
||||
*/
|
||||
/*****************************************************************************/
|
||||
#if !defined(EASYCAP_LOW_H)
|
||||
#define EASYCAP_LOW_H
|
||||
|
||||
extern int easycap_debug;
|
||||
extern int easycap_gain;
|
||||
extern struct easycap_dongle easycap_dongle[];
|
||||
extern struct easycap_dongle easycapdc60_dongle[];
|
||||
|
||||
#endif /*EASYCAP_LOW_H*/
|
|
@ -29,30 +29,17 @@
|
|||
/*****************************************************************************/
|
||||
|
||||
#include "easycap.h"
|
||||
#include "easycap_standard.h"
|
||||
#include "easycap_ioctl.h"
|
||||
#include "easycap_main.h"
|
||||
|
||||
int easycap_debug;
|
||||
static int easycap_bars;
|
||||
static int easycap_bars = 1;
|
||||
int easycap_gain = 16;
|
||||
module_param_named(debug, easycap_debug, int, S_IRUGO | S_IWUSR);
|
||||
module_param_named(bars, easycap_bars, int, S_IRUGO | S_IWUSR);
|
||||
module_param_named(gain, easycap_gain, int, S_IRUGO | S_IWUSR);
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* dongle_this IS INDISPENSIBLY static BECAUSE FUNCTION easycap_usb_probe()
|
||||
* IS CALLED SUCCESSIVELY FOR INTERFACES 0, 1, 2 AND THE POINTER peasycap
|
||||
* ALLOCATED DURING THE PROBING OF INTERFACE 0 MUST BE REMEMBERED WHEN
|
||||
* PROBING INTERFACES 1 AND 2.
|
||||
*
|
||||
* IOCTL LOCKING IS DONE AT MODULE LEVEL, NOT DEVICE LEVEL.
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
struct easycap_dongle easycap_dongle[DONGLE_MANY];
|
||||
static int dongle_this;
|
||||
static int dongle_done;
|
||||
struct easycap_dongle easycapdc60_dongle[DONGLE_MANY];
|
||||
static struct mutex mutex_dongle;
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
|
@ -120,28 +107,6 @@ const struct v4l2_file_operations v4l2_fops = {
|
|||
#endif /*EASYCAP_NEEDS_V4L2_FOPS*/
|
||||
#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
|
||||
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/*
|
||||
* PARAMETERS USED WHEN REGISTERING THE AUDIO INTERFACE
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
const struct file_operations easysnd_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = easysnd_open,
|
||||
.release = easysnd_release,
|
||||
#if defined(EASYCAP_NEEDS_UNLOCKED_IOCTL)
|
||||
.unlocked_ioctl = easysnd_ioctl_noinode,
|
||||
#else
|
||||
.ioctl = easysnd_ioctl,
|
||||
#endif /*EASYCAP_NEEDS_UNLOCKED_IOCTL*/
|
||||
.read = easysnd_read,
|
||||
.llseek = no_llseek,
|
||||
};
|
||||
struct usb_class_driver easysnd_class = {
|
||||
.name = "usb/easysnd%d",
|
||||
.fops = &easysnd_fops,
|
||||
.minor_base = USB_SKEL_MINOR_BASE,
|
||||
};
|
||||
/****************************************************************************/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
|
@ -155,7 +120,7 @@ int k;
|
|||
if (NULL == peasycap)
|
||||
return -2;
|
||||
for (k = 0; k < DONGLE_MANY; k++) {
|
||||
if (easycap_dongle[k].peasycap == peasycap) {
|
||||
if (easycapdc60_dongle[k].peasycap == peasycap) {
|
||||
peasycap->isdongle = k;
|
||||
return k;
|
||||
}
|
||||
|
@ -1055,9 +1020,10 @@ for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) {
|
|||
m++;
|
||||
}
|
||||
}
|
||||
JOM(4, "easysnd_delete(): isoc audio buffers freed: %i pages\n", \
|
||||
JOM(4, "easyoss_delete(): isoc audio buffers freed: %i pages\n", \
|
||||
m * (0x01 << AUDIO_ISOC_ORDER));
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if !defined(EASYCAP_NEEDS_ALSA)
|
||||
JOM(4, "freeing audio buffers.\n");
|
||||
gone = 0;
|
||||
for (k = 0; k < peasycap->audio_buffer_page_many; k++) {
|
||||
|
@ -1068,7 +1034,8 @@ for (k = 0; k < peasycap->audio_buffer_page_many; k++) {
|
|||
gone++;
|
||||
}
|
||||
}
|
||||
JOM(4, "easysnd_delete(): audio buffers freed: %i pages\n", gone);
|
||||
JOM(4, "easyoss_delete(): audio buffers freed: %i pages\n", gone);
|
||||
#endif /*!EASYCAP_NEEDS_ALSA*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
JOM(4, "freeing easycap structure.\n");
|
||||
allocation_video_urb = peasycap->allocation_video_urb;
|
||||
|
@ -1081,12 +1048,20 @@ allocation_audio_struct = peasycap->allocation_audio_struct;
|
|||
registered_audio = peasycap->registered_audio;
|
||||
|
||||
kfree(peasycap);
|
||||
|
||||
if (0 <= kd && DONGLE_MANY > kd) {
|
||||
easycap_dongle[kd].peasycap = (struct easycap *)NULL;
|
||||
JOT(4, " null-->easycap_dongle[%i].peasycap\n", kd);
|
||||
allocation_video_struct -= sizeof(struct easycap);
|
||||
if (mutex_lock_interruptible(&mutex_dongle)) {
|
||||
SAY("ERROR: cannot down mutex_dongle\n");
|
||||
} else {
|
||||
JOM(4, "locked mutex_dongle\n");
|
||||
easycapdc60_dongle[kd].peasycap = (struct easycap *)NULL;
|
||||
mutex_unlock(&mutex_dongle);
|
||||
JOM(4, "unlocked mutex_dongle\n");
|
||||
JOT(4, " null-->easycapdc60_dongle[%i].peasycap\n", kd);
|
||||
allocation_video_struct -= sizeof(struct easycap);
|
||||
}
|
||||
} else {
|
||||
SAY("ERROR: cannot purge easycap_dongle[].peasycap");
|
||||
SAY("ERROR: cannot purge easycapdc60_dongle[].peasycap");
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
SAY("%8i= video urbs after all deletions\n", allocation_video_urb);
|
||||
|
@ -1131,11 +1106,12 @@ if (NULL == peasycap->pusb_device) {
|
|||
/*---------------------------------------------------------------------------*/
|
||||
kd = isdongle(peasycap);
|
||||
if (0 <= kd && DONGLE_MANY > kd) {
|
||||
if (mutex_lock_interruptible(&easycap_dongle[kd].mutex_video)) {
|
||||
SAY("ERROR: cannot down easycap_dongle[%i].mutex_video\n", kd);
|
||||
if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_video)) {
|
||||
SAY("ERROR: cannot down "
|
||||
"easycapdc60_dongle[%i].mutex_video\n", kd);
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
JOM(4, "locked easycap_dongle[%i].mutex_video\n", kd);
|
||||
JOM(4, "locked easycapdc60_dongle[%i].mutex_video\n", kd);
|
||||
/*-------------------------------------------------------------------*/
|
||||
/*
|
||||
* MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER
|
||||
|
@ -1147,24 +1123,24 @@ if (0 <= kd && DONGLE_MANY > kd) {
|
|||
return -ERESTARTSYS;
|
||||
if (NULL == file) {
|
||||
SAY("ERROR: file is NULL\n");
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
peasycap = file->private_data;
|
||||
if (NULL == peasycap) {
|
||||
SAY("ERROR: peasycap is NULL\n");
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
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);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
if (NULL == peasycap->pusb_device) {
|
||||
SAM("ERROR: peasycap->pusb_device is NULL\n");
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
} else
|
||||
|
@ -1179,7 +1155,7 @@ if (0 <= kd && DONGLE_MANY > kd) {
|
|||
/*---------------------------------------------------------------------------*/
|
||||
rc = easycap_dqbuf(peasycap, 0);
|
||||
peasycap->polled = 1;
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
if (0 == rc)
|
||||
return POLLIN | POLLRDNORM;
|
||||
else
|
||||
|
@ -3391,20 +3367,13 @@ return;
|
|||
/*****************************************************************************/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
*
|
||||
* FIXME
|
||||
*
|
||||
*
|
||||
* THIS FUNCTION ASSUMES THAT, ON EACH AND EVERY OCCASION THAT THE EasyCAP
|
||||
* IS PHYSICALLY PLUGGED IN, INTERFACE 0 IS PROBED FIRST.
|
||||
* IF THIS IS NOT TRUE, THERE IS THE POSSIBILITY OF AN Oops.
|
||||
*
|
||||
* THIS HAS NEVER BEEN A PROBLEM IN PRACTICE, BUT SOMETHING SEEMS WRONG HERE.
|
||||
* WHEN THE EasyCAP IS PHYSICALLY PLUGGED IN, THIS FUNCTION IS CALLED THREE
|
||||
* TIMES, ONCE FOR EACH OF THE THREE INTERFACES. BEWARE.
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
easycap_usb_probe(struct usb_interface *pusb_interface, \
|
||||
const struct usb_device_id *id)
|
||||
const struct usb_device_id *pusb_device_id)
|
||||
{
|
||||
struct usb_device *pusb_device, *pusb_device1;
|
||||
struct usb_host_interface *pusb_host_interface;
|
||||
|
@ -3413,6 +3382,7 @@ struct usb_interface_descriptor *pusb_interface_descriptor;
|
|||
struct usb_interface_assoc_descriptor *pusb_interface_assoc_descriptor;
|
||||
struct urb *purb;
|
||||
struct easycap *peasycap;
|
||||
int ndong;
|
||||
struct data_urb *pdata_urb;
|
||||
size_t wMaxPacketSize;
|
||||
int ISOCwMaxPacketSize;
|
||||
|
@ -3434,24 +3404,19 @@ int maxpacketsize;
|
|||
__u16 mask;
|
||||
__s32 value;
|
||||
struct easycap_format *peasycap_format;
|
||||
|
||||
JOT(4, "\n");
|
||||
|
||||
if (!dongle_done) {
|
||||
dongle_done = 1;
|
||||
for (k = 0; k < DONGLE_MANY; k++) {
|
||||
easycap_dongle[k].peasycap = (struct easycap *)NULL;
|
||||
mutex_init(&easycap_dongle[k].mutex_video);
|
||||
mutex_init(&easycap_dongle[k].mutex_audio);
|
||||
}
|
||||
}
|
||||
|
||||
peasycap = (struct easycap *)NULL;
|
||||
/*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*/
|
||||
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
|
||||
|
||||
if ((struct usb_interface *)NULL == pusb_interface) {
|
||||
SAY("ERROR: pusb_interface is NULL\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
peasycap = (struct easycap *)NULL;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* GET POINTER TO STRUCTURE usb_device
|
||||
|
@ -3472,9 +3437,7 @@ if ((unsigned long int)pusb_device1 != (unsigned long int)pusb_device) {
|
|||
JOT(4, "ERROR: pusb_device1 != pusb_device\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
JOT(4, "bNumConfigurations=%i\n", pusb_device->descriptor.bNumConfigurations);
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
pusb_host_interface = pusb_interface->cur_altsetting;
|
||||
if (NULL == pusb_host_interface) {
|
||||
|
@ -3553,9 +3516,6 @@ JOT(4, "intf[%i]: pusb_interface_assoc_descriptor is NULL\n", \
|
|||
*
|
||||
* THE POINTER peasycap TO THE struct easycap IS REMEMBERED WHEN
|
||||
* INTERFACES 1 AND 2 ARE PROBED.
|
||||
*
|
||||
* IF TWO EasyCAPs ARE PLUGGED IN NEARLY SIMULTANEOUSLY THERE WILL
|
||||
* BE TROUBLE. BEWARE.
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
if (0 == bInterfaceNumber) {
|
||||
|
@ -3580,6 +3540,7 @@ if (0 == bInterfaceNumber) {
|
|||
* PERFORM URGENT INTIALIZATIONS ...
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
peasycap->minor = -1;
|
||||
strcpy(&peasycap->telltale[0], TELLTALE);
|
||||
kref_init(&peasycap->kref);
|
||||
JOM(8, "intf[%i]: after kref_init(..._video) " \
|
||||
|
@ -3588,29 +3549,43 @@ if (0 == bInterfaceNumber) {
|
|||
|
||||
init_waitqueue_head(&peasycap->wq_video);
|
||||
init_waitqueue_head(&peasycap->wq_audio);
|
||||
init_waitqueue_head(&peasycap->wq_trigger);
|
||||
|
||||
for (dongle_this = 0; dongle_this < DONGLE_MANY; dongle_this++) {
|
||||
if (NULL == easycap_dongle[dongle_this].peasycap) {
|
||||
if (0 == mutex_is_locked(&easycap_dongle\
|
||||
[dongle_this].mutex_video)) {
|
||||
if (0 == mutex_is_locked(&easycap_dongle\
|
||||
[dongle_this].mutex_audio)) {
|
||||
easycap_dongle\
|
||||
[dongle_this].peasycap = \
|
||||
peasycap;
|
||||
JOM(8, "intf[%i]: peasycap-->easycap" \
|
||||
if (mutex_lock_interruptible(&mutex_dongle)) {
|
||||
SAY("ERROR: cannot down mutex_dongle\n");
|
||||
return -ERESTARTSYS;
|
||||
} else {
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* FOR INTERFACES 1 AND 2 THE POINTER peasycap WILL NEED TO
|
||||
* TO BE THE SAME AS THAT ALLOCATED NOW FOR INTERFACE 0.
|
||||
*
|
||||
* NORMALLY ndong WILL NOT HAVE CHANGED SINCE INTERFACE 0 WAS
|
||||
* PROBED, BUT THIS MAY NOT BE THE CASE IF, FOR EXAMPLE, TWO
|
||||
* EASYCAPs ARE PLUGGED IN SIMULTANEOUSLY.
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
for (ndong = 0; ndong < DONGLE_MANY; ndong++) {
|
||||
if ((NULL == easycapdc60_dongle[ndong].peasycap) && \
|
||||
(!mutex_is_locked(&easycapdc60_dongle\
|
||||
[ndong].mutex_video)) && \
|
||||
(!mutex_is_locked(&easycapdc60_dongle\
|
||||
[ndong].mutex_audio))) {
|
||||
easycapdc60_dongle[ndong].peasycap = peasycap;
|
||||
peasycap->isdongle = ndong;
|
||||
JOM(8, "intf[%i]: peasycap-->easycap" \
|
||||
"_dongle[%i].peasycap\n", \
|
||||
bInterfaceNumber, dongle_this);
|
||||
break;
|
||||
}
|
||||
bInterfaceNumber, ndong);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (DONGLE_MANY <= ndong) {
|
||||
SAM("ERROR: too many dongles\n");
|
||||
mutex_unlock(&mutex_dongle);
|
||||
return -ENOMEM;
|
||||
}
|
||||
mutex_unlock(&mutex_dongle);
|
||||
}
|
||||
if (DONGLE_MANY <= dongle_this) {
|
||||
SAM("ERROR: too many dongles\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
peasycap->allocation_video_struct = sizeof(struct easycap);
|
||||
peasycap->allocation_video_page = 0;
|
||||
peasycap->allocation_video_urb = 0;
|
||||
|
@ -3778,26 +3753,56 @@ if (0 == bInterfaceNumber) {
|
|||
JOM(4, "finished initialization\n");
|
||||
} else {
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* FOR INTERFACES 1 AND 2 THE POINTER peasycap IS OBTAINED BY ASSUMING
|
||||
* THAT dongle_this HAS NOT CHANGED SINCE INTERFACE 0 WAS PROBED. IF
|
||||
* THIS IS NOT THE CASE, FOR EXAMPLE WHEN TWO EASYCAPs ARE PLUGGED IN
|
||||
* SIMULTANEOUSLY, THERE WILL BE SERIOUS TROUBLE.
|
||||
*/
|
||||
/*
|
||||
* FIXME
|
||||
*
|
||||
* IDENTIFY THE APPROPRIATE POINTER peasycap FOR INTERFACES 1 AND 2.
|
||||
* THE ADDRESS OF peasycap->pusb_device IS RELUCTANTLY USED FOR THIS PURPOSE.
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
if ((0 > dongle_this) || (DONGLE_MANY <= dongle_this)) {
|
||||
SAY("ERROR: bad dongle count\n");
|
||||
return -EFAULT;
|
||||
for (ndong = 0; ndong < DONGLE_MANY; ndong++) {
|
||||
if (pusb_device == easycapdc60_dongle[ndong].peasycap->\
|
||||
pusb_device) {
|
||||
peasycap = easycapdc60_dongle[ndong].peasycap;
|
||||
JOT(8, "intf[%i]: easycapdc60_dongle[%i].peasycap-->" \
|
||||
"peasycap\n", bInterfaceNumber, ndong);
|
||||
break;
|
||||
}
|
||||
}
|
||||
peasycap = easycap_dongle[dongle_this].peasycap;
|
||||
JOT(8, "intf[%i]: easycap_dongle[%i].peasycap-->peasycap\n", \
|
||||
bInterfaceNumber, dongle_this);
|
||||
|
||||
if ((struct easycap *)NULL == peasycap) {
|
||||
if (DONGLE_MANY <= ndong) {
|
||||
SAY("ERROR: peasycap is unknown when probing interface %i\n", \
|
||||
bInterfaceNumber);
|
||||
return -ENODEV;
|
||||
}
|
||||
if (NULL == peasycap) {
|
||||
SAY("ERROR: peasycap is NULL when probing interface %i\n", \
|
||||
bInterfaceNumber);
|
||||
return -EFAULT;
|
||||
return -ENODEV;
|
||||
}
|
||||
#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 -ENODEV;
|
||||
}
|
||||
peasycap = (struct easycap *) \
|
||||
container_of(pv4l2_device, struct easycap, v4l2_device);
|
||||
}
|
||||
#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/
|
||||
#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
if ((USB_CLASS_VIDEO == bInterfaceClass) || \
|
||||
|
@ -4368,6 +4373,7 @@ case 0: {
|
|||
} else {
|
||||
(peasycap->registered_video)++;
|
||||
SAM("easycap attached to minor #%d\n", pusb_interface->minor);
|
||||
peasycap->minor = pusb_interface->minor;
|
||||
break;
|
||||
}
|
||||
/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
|
||||
|
@ -4383,7 +4389,7 @@ case 0: {
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* FIXME
|
||||
* FIXME
|
||||
*
|
||||
*
|
||||
* THIS IS BELIEVED TO BE HARMLESS, BUT MAY WELL BE UNNECESSARY OR WRONG:
|
||||
|
@ -4414,9 +4420,11 @@ case 0: {
|
|||
(peasycap->registered_video)++;
|
||||
SAM("registered with videodev: %i=minor\n", \
|
||||
peasycap->video_device.minor);
|
||||
peasycap->minor = peasycap->video_device.minor;
|
||||
}
|
||||
#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
|
||||
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
|
||||
|
||||
break;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
@ -4426,8 +4434,11 @@ case 0: {
|
|||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
case 1: {
|
||||
#if defined(EASYCAP_SILENT)
|
||||
return -ENOENT;
|
||||
#endif /*EASYCAP_SILENT*/
|
||||
if (!peasycap) {
|
||||
SAM("ERROR: peasycap is NULL\n");
|
||||
SAM("MISTAKE: peasycap is NULL\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
@ -4442,6 +4453,9 @@ case 1: {
|
|||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
case 2: {
|
||||
#if defined(EASYCAP_SILENT)
|
||||
return -ENOENT;
|
||||
#endif /*EASYCAP_SILENT*/
|
||||
if (!peasycap) {
|
||||
SAM("MISTAKE: peasycap is NULL\n");
|
||||
return -EFAULT;
|
||||
|
@ -4467,14 +4481,14 @@ case 2: {
|
|||
}
|
||||
if (9 == peasycap->audio_isoc_maxframesize) {
|
||||
peasycap->ilk |= 0x02;
|
||||
SAM("hardware is FOUR-CVBS\n");
|
||||
SAM("audio hardware is microphone\n");
|
||||
peasycap->microphone = true;
|
||||
peasycap->audio_pages_per_fragment = 4;
|
||||
peasycap->audio_pages_per_fragment = PAGES_PER_AUDIO_FRAGMENT;
|
||||
} else if (256 == peasycap->audio_isoc_maxframesize) {
|
||||
peasycap->ilk &= ~0x02;
|
||||
SAM("hardware is CVBS+S-VIDEO\n");
|
||||
SAM("audio hardware is AC'97\n");
|
||||
peasycap->microphone = false;
|
||||
peasycap->audio_pages_per_fragment = 4;
|
||||
peasycap->audio_pages_per_fragment = PAGES_PER_AUDIO_FRAGMENT;
|
||||
} else {
|
||||
SAM("hardware is unidentified:\n");
|
||||
SAM("%i=audio_isoc_maxframesize\n", \
|
||||
|
@ -4496,7 +4510,7 @@ case 2: {
|
|||
JOM(4, "%6i=audio_buffer_page_many\n", \
|
||||
peasycap->audio_buffer_page_many);
|
||||
|
||||
peasycap->audio_isoc_framesperdesc = 128;
|
||||
peasycap->audio_isoc_framesperdesc = AUDIO_ISOC_FRAMESPERDESC;
|
||||
|
||||
JOM(4, "%i=audio_isoc_framesperdesc\n", \
|
||||
peasycap->audio_isoc_framesperdesc);
|
||||
|
@ -4548,6 +4562,7 @@ case 2: {
|
|||
INIT_LIST_HEAD(&(peasycap->urb_audio_head));
|
||||
peasycap->purb_audio_head = &(peasycap->urb_audio_head);
|
||||
|
||||
#if !defined(EASYCAP_NEEDS_ALSA)
|
||||
JOM(4, "allocating an audio buffer\n");
|
||||
JOM(4, ".... scattered over %i pages\n", \
|
||||
peasycap->audio_buffer_page_many);
|
||||
|
@ -4572,6 +4587,7 @@ case 2: {
|
|||
peasycap->audio_fill = 0;
|
||||
peasycap->audio_read = 0;
|
||||
JOM(4, "allocation of audio buffer done: %i pages\n", k);
|
||||
#endif /*!EASYCAP_NEEDS_ALSA*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
JOM(4, "allocating %i isoc audio buffers of size %i\n", \
|
||||
AUDIO_ISOC_BUFFER_MANY, peasycap->audio_isoc_buffer_size);
|
||||
|
@ -4646,7 +4662,11 @@ case 2: {
|
|||
"peasycap->audio_isoc_buffer[.].pgo;\n");
|
||||
JOM(4, " purb->transfer_buffer_length = %i;\n", \
|
||||
peasycap->audio_isoc_buffer_size);
|
||||
JOM(4, " purb->complete = easysnd_complete;\n");
|
||||
#if defined(EASYCAP_NEEDS_ALSA)
|
||||
JOM(4, " purb->complete = easycap_alsa_complete;\n");
|
||||
#else
|
||||
JOM(4, " purb->complete = easyoss_complete;\n");
|
||||
#endif /*EASYCAP_NEEDS_ALSA*/
|
||||
JOM(4, " purb->context = peasycap;\n");
|
||||
JOM(4, " purb->start_frame = 0;\n");
|
||||
JOM(4, " purb->number_of_packets = %i;\n", \
|
||||
|
@ -4669,7 +4689,11 @@ case 2: {
|
|||
purb->transfer_buffer = peasycap->audio_isoc_buffer[k].pgo;
|
||||
purb->transfer_buffer_length = \
|
||||
peasycap->audio_isoc_buffer_size;
|
||||
purb->complete = easysnd_complete;
|
||||
#if defined(EASYCAP_NEEDS_ALSA)
|
||||
purb->complete = easycap_alsa_complete;
|
||||
#else
|
||||
purb->complete = easyoss_complete;
|
||||
#endif /*EASYCAP_NEEDS_ALSA*/
|
||||
purb->context = peasycap;
|
||||
purb->start_frame = 0;
|
||||
purb->number_of_packets = peasycap->audio_isoc_framesperdesc;
|
||||
|
@ -4692,9 +4716,24 @@ case 2: {
|
|||
* THE AUDIO DEVICE CAN BE REGISTERED NOW, AS IT IS READY.
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
rc = usb_register_dev(pusb_interface, &easysnd_class);
|
||||
#if defined(EASYCAP_NEEDS_ALSA)
|
||||
JOM(4, "initializing ALSA card\n");
|
||||
|
||||
rc = easycap_alsa_probe(peasycap);
|
||||
if (0 != rc) {
|
||||
err("Not able to get a minor for this device.");
|
||||
err("easycap_alsa_probe() returned %i\n", rc);
|
||||
return -ENODEV;
|
||||
} else {
|
||||
JOM(8, "kref_get() with %i=peasycap->kref.refcount.counter\n",\
|
||||
(int)peasycap->kref.refcount.counter);
|
||||
kref_get(&peasycap->kref);
|
||||
(peasycap->registered_audio)++;
|
||||
}
|
||||
|
||||
#else /*EASYCAP_NEEDS_ALSA*/
|
||||
rc = usb_register_dev(pusb_interface, &easyoss_class);
|
||||
if (0 != rc) {
|
||||
SAY("ERROR: usb_register_dev() failed\n");
|
||||
usb_set_intfdata(pusb_interface, NULL);
|
||||
return -ENODEV;
|
||||
} else {
|
||||
|
@ -4708,7 +4747,9 @@ case 2: {
|
|||
* LET THE USER KNOW WHAT NODE THE AUDIO DEVICE IS ATTACHED TO.
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
SAM("easysnd attached to minor #%d\n", pusb_interface->minor);
|
||||
SAM("easyoss attached to minor #%d\n", pusb_interface->minor);
|
||||
#endif /*EASYCAP_NEEDS_ALSA*/
|
||||
|
||||
break;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -4721,7 +4762,7 @@ default: {
|
|||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
JOM(4, "ends successfully for interface %i\n", \
|
||||
SAM("ends successfully for interface %i\n", \
|
||||
pusb_interface_descriptor->bInterfaceNumber);
|
||||
return 0;
|
||||
}
|
||||
|
@ -4730,6 +4771,8 @@ return 0;
|
|||
/*
|
||||
* WHEN THIS FUNCTION IS CALLED THE EasyCAP HAS ALREADY BEEN PHYSICALLY
|
||||
* UNPLUGGED. HENCE peasycap->pusb_device IS NO LONGER VALID.
|
||||
*
|
||||
* THIS FUNCTION AFFECTS BOTH OSS AND ALSA. BEWARE.
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
@ -4881,14 +4924,15 @@ switch (bInterfaceNumber) {
|
|||
case 0: {
|
||||
if (0 <= kd && DONGLE_MANY > kd) {
|
||||
wake_up_interruptible(&peasycap->wq_video);
|
||||
JOM(4, "about to lock easycap_dongle[%i].mutex_video\n", kd);
|
||||
if (mutex_lock_interruptible(&easycap_dongle[kd].\
|
||||
JOM(4, "about to lock easycapdc60_dongle[%i].mutex_video\n", \
|
||||
kd);
|
||||
if (mutex_lock_interruptible(&easycapdc60_dongle[kd].\
|
||||
mutex_video)) {
|
||||
SAY("ERROR: cannot lock easycap_dongle[%i]." \
|
||||
SAY("ERROR: cannot lock easycapdc60_dongle[%i]." \
|
||||
"mutex_video\n", kd);
|
||||
return;
|
||||
}
|
||||
JOM(4, "locked easycap_dongle[%i].mutex_video\n", kd);
|
||||
JOM(4, "locked easycapdc60_dongle[%i].mutex_video\n", kd);
|
||||
} else
|
||||
SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -4907,7 +4951,7 @@ case 0: {
|
|||
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);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
return;
|
||||
}
|
||||
v4l2_device_disconnect(&peasycap->v4l2_device);
|
||||
|
@ -4924,34 +4968,47 @@ case 0: {
|
|||
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
|
||||
|
||||
if (0 <= kd && DONGLE_MANY > kd) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
JOM(4, "unlocked easycap_dongle[%i].mutex_video\n", kd);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
JOM(4, "unlocked easycapdc60_dongle[%i].mutex_video\n", kd);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
if (0 <= kd && DONGLE_MANY > kd) {
|
||||
wake_up_interruptible(&peasycap->wq_audio);
|
||||
JOM(4, "about to lock easycap_dongle[%i].mutex_audio\n", kd);
|
||||
if (mutex_lock_interruptible(&easycap_dongle[kd].\
|
||||
JOM(4, "about to lock easycapdc60_dongle[%i].mutex_audio\n", \
|
||||
kd);
|
||||
if (mutex_lock_interruptible(&easycapdc60_dongle[kd].\
|
||||
mutex_audio)) {
|
||||
SAY("ERROR: cannot lock easycap_dongle[%i]." \
|
||||
SAY("ERROR: cannot lock easycapdc60_dongle[%i]." \
|
||||
"mutex_audio\n", kd);
|
||||
return;
|
||||
}
|
||||
JOM(4, "locked easycap_dongle[%i].mutex_audio\n", kd);
|
||||
JOM(4, "locked easycapdc60_dongle[%i].mutex_audio\n", kd);
|
||||
} else
|
||||
SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd);
|
||||
#if defined(EASYCAP_NEEDS_ALSA)
|
||||
|
||||
usb_deregister_dev(pusb_interface, &easysnd_class);
|
||||
|
||||
|
||||
if (0 != snd_card_free(peasycap->psnd_card)) {
|
||||
SAY("ERROR: snd_card_free() failed\n");
|
||||
} else {
|
||||
peasycap->psnd_card = (struct snd_card *)NULL;
|
||||
(peasycap->registered_audio)--;
|
||||
}
|
||||
|
||||
|
||||
#else /*EASYCAP_NEEDS_ALSA*/
|
||||
usb_deregister_dev(pusb_interface, &easyoss_class);
|
||||
(peasycap->registered_audio)--;
|
||||
|
||||
JOM(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber);
|
||||
SAM("easysnd detached from minor #%d\n", minor);
|
||||
SAM("easyoss detached from minor #%d\n", minor);
|
||||
#endif /*EASYCAP_NEEDS_ALSA*/
|
||||
|
||||
if (0 <= kd && DONGLE_MANY > kd) {
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_audio);
|
||||
JOM(4, "unlocked easycap_dongle[%i].mutex_audio\n", kd);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
|
||||
JOM(4, "unlocked easycapdc60_dongle[%i].mutex_audio\n", kd);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -4961,6 +5018,7 @@ case 2: {
|
|||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* CALL easycap_delete() IF NO REMAINING REFERENCES TO peasycap
|
||||
* (ALSO WHEN ALSA HAS BEEN IN USE)
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
if (!peasycap->kref.refcount.counter) {
|
||||
|
@ -4970,32 +5028,34 @@ if (!peasycap->kref.refcount.counter) {
|
|||
return;
|
||||
}
|
||||
if (0 <= kd && DONGLE_MANY > kd) {
|
||||
JOM(4, "about to lock easycap_dongle[%i].mutex_video\n", kd);
|
||||
if (mutex_lock_interruptible(&easycap_dongle[kd].mutex_video)) {
|
||||
SAY("ERROR: cannot down easycap_dongle[%i].mutex_video\n", kd);
|
||||
JOM(4, "about to lock easycapdc60_dongle[%i].mutex_video\n", kd);
|
||||
if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_video)) {
|
||||
SAY("ERROR: cannot down "
|
||||
"easycapdc60_dongle[%i].mutex_video\n", kd);
|
||||
SAM("ending unsuccessfully: may cause memory leak\n");
|
||||
return;
|
||||
}
|
||||
JOM(4, "locked easycap_dongle[%i].mutex_video\n", kd);
|
||||
JOM(4, "about to lock easycap_dongle[%i].mutex_audio\n", kd);
|
||||
if (mutex_lock_interruptible(&easycap_dongle[kd].mutex_audio)) {
|
||||
SAY("ERROR: cannot down easycap_dongle[%i].mutex_audio\n", kd);
|
||||
mutex_unlock(&(easycap_dongle[kd].mutex_video));
|
||||
JOM(4, "unlocked easycap_dongle[%i].mutex_video\n", kd);
|
||||
JOM(4, "locked easycapdc60_dongle[%i].mutex_video\n", kd);
|
||||
JOM(4, "about to lock easycapdc60_dongle[%i].mutex_audio\n", kd);
|
||||
if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_audio)) {
|
||||
SAY("ERROR: cannot down "
|
||||
"easycapdc60_dongle[%i].mutex_audio\n", kd);
|
||||
mutex_unlock(&(easycapdc60_dongle[kd].mutex_video));
|
||||
JOM(4, "unlocked easycapdc60_dongle[%i].mutex_video\n", kd);
|
||||
SAM("ending unsuccessfully: may cause memory leak\n");
|
||||
return;
|
||||
}
|
||||
JOM(4, "locked easycap_dongle[%i].mutex_audio\n", kd);
|
||||
JOM(4, "locked easycapdc60_dongle[%i].mutex_audio\n", kd);
|
||||
}
|
||||
JOM(4, "intf[%i]: %i=peasycap->kref.refcount.counter\n", \
|
||||
bInterfaceNumber, (int)peasycap->kref.refcount.counter);
|
||||
kref_put(&peasycap->kref, easycap_delete);
|
||||
JOT(4, "intf[%i]: kref_put() done.\n", bInterfaceNumber);
|
||||
if (0 <= kd && DONGLE_MANY > kd) {
|
||||
mutex_unlock(&(easycap_dongle[kd].mutex_audio));
|
||||
JOT(4, "unlocked easycap_dongle[%i].mutex_audio\n", kd);
|
||||
mutex_unlock(&easycap_dongle[kd].mutex_video);
|
||||
JOT(4, "unlocked easycap_dongle[%i].mutex_video\n", kd);
|
||||
mutex_unlock(&(easycapdc60_dongle[kd].mutex_audio));
|
||||
JOT(4, "unlocked easycapdc60_dongle[%i].mutex_audio\n", kd);
|
||||
mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
|
||||
JOT(4, "unlocked easycapdc60_dongle[%i].mutex_video\n", kd);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
JOM(4, "ends\n");
|
||||
|
@ -5005,25 +5065,31 @@ return;
|
|||
int __init
|
||||
easycap_module_init(void)
|
||||
{
|
||||
int result;
|
||||
int k, rc;
|
||||
|
||||
SAY("========easycap=======\n");
|
||||
JOT(4, "begins. %i=debug %i=bars %i=gain\n", easycap_debug, easycap_bars, \
|
||||
easycap_gain);
|
||||
SAY("version: " EASYCAP_DRIVER_VERSION "\n");
|
||||
|
||||
mutex_init(&mutex_dongle);
|
||||
for (k = 0; k < DONGLE_MANY; k++) {
|
||||
easycapdc60_dongle[k].peasycap = (struct easycap *)NULL;
|
||||
mutex_init(&easycapdc60_dongle[k].mutex_video);
|
||||
mutex_init(&easycapdc60_dongle[k].mutex_audio);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* REGISTER THIS DRIVER WITH THE USB SUBSYTEM.
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
JOT(4, "registering driver easycap\n");
|
||||
|
||||
result = usb_register(&easycap_usb_driver);
|
||||
if (0 != result)
|
||||
SAY("ERROR: usb_register returned %i\n", result);
|
||||
rc = usb_register(&easycap_usb_driver);
|
||||
if (0 != rc)
|
||||
SAY("ERROR: usb_register returned %i\n", rc);
|
||||
|
||||
JOT(4, "ends\n");
|
||||
return result;
|
||||
return rc;
|
||||
}
|
||||
/*****************************************************************************/
|
||||
void __exit
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/*****************************************************************************
|
||||
* *
|
||||
* easycap_main.h *
|
||||
* *
|
||||
*****************************************************************************/
|
||||
/*
|
||||
*
|
||||
* Copyright (C) 2010 R.M. Thomas <rmthomas@sciolus.org>
|
||||
*
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
/*****************************************************************************/
|
||||
#if !defined(EASYCAP_MAIN_H)
|
||||
#define EASYCAP_MAIN_H
|
||||
|
||||
extern struct easycap_standard easycap_standard[];
|
||||
extern struct easycap_format easycap_format[];
|
||||
extern struct v4l2_queryctrl easycap_control[];
|
||||
extern struct usb_driver easycap_usb_driver;
|
||||
#if defined(EASYCAP_NEEDS_ALSA)
|
||||
extern struct snd_pcm_ops easycap_alsa_ops;
|
||||
extern struct snd_pcm_hardware easycap_pcm_hardware;
|
||||
extern struct snd_card *psnd_card;
|
||||
#else
|
||||
extern struct usb_class_driver easyoss_class;
|
||||
extern const struct file_operations easyoss_fops;
|
||||
#endif /*EASYCAP_NEEDS_ALSA*/
|
||||
|
||||
#endif /*EASYCAP_MAIN_H*/
|
|
@ -26,7 +26,7 @@
|
|||
/*****************************************************************************/
|
||||
|
||||
#include "easycap.h"
|
||||
#include "easycap_debug.h"
|
||||
#include "easycap_settings.h"
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************
|
||||
* *
|
||||
* easycap_standard.h *
|
||||
* easycap_settings.h *
|
||||
* *
|
||||
*****************************************************************************/
|
||||
/*
|
||||
|
@ -24,4 +24,11 @@
|
|||
*
|
||||
*/
|
||||
/*****************************************************************************/
|
||||
extern struct easycap_standard easycap_standard[];
|
||||
#if !defined(EASYCAP_SETTINGS_H)
|
||||
#define EASYCAP_SETTINGS_H
|
||||
|
||||
extern int easycap_debug;
|
||||
extern int easycap_gain;
|
||||
extern struct easycap_dongle easycapdc60_dongle[];
|
||||
|
||||
#endif /*EASYCAP_SETTINGS_H*/
|
File diff suppressed because it is too large
Load Diff
|
@ -24,5 +24,19 @@
|
|||
*
|
||||
*/
|
||||
/*****************************************************************************/
|
||||
#if !defined(EASYCAP_SOUND_H)
|
||||
#define EASYCAP_SOUND_H
|
||||
|
||||
extern int easycap_debug;
|
||||
extern int easycap_gain;
|
||||
extern struct easycap_dongle easycapdc60_dongle[];
|
||||
extern struct easycap *peasycap;
|
||||
extern struct usb_driver easycap_usb_driver;
|
||||
#if defined(EASYCAP_NEEDS_ALSA)
|
||||
extern struct snd_pcm_hardware easycap_pcm_hardware;
|
||||
#else
|
||||
extern struct usb_class_driver easyoss_class;
|
||||
extern const struct file_operations easyoss_fops;
|
||||
#endif /*EASYCAP_NEEDS_ALSA*/
|
||||
|
||||
#endif /*EASYCAP_SOUND_H*/
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
/*****************************************************************************/
|
||||
|
||||
#include "easycap.h"
|
||||
#include "easycap_debug.h"
|
||||
#include "easycap_testcard.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
#define TESTCARD_BYTESPERLINE (2 * 720)
|
||||
|
@ -397,7 +397,7 @@ int tones[2048] = {
|
|||
};
|
||||
/*****************************************************************************/
|
||||
void
|
||||
easysnd_testtone(struct easycap *peasycap, int audio_fill)
|
||||
easyoss_testtone(struct easycap *peasycap, int audio_fill)
|
||||
{
|
||||
int i1;
|
||||
unsigned char *p2;
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/*****************************************************************************
|
||||
* *
|
||||
* easycap_testcard.h *
|
||||
* *
|
||||
*****************************************************************************/
|
||||
/*
|
||||
*
|
||||
* Copyright (C) 2010 R.M. Thomas <rmthomas@sciolus.org>
|
||||
*
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
/*****************************************************************************/
|
||||
#if !defined(EASYCAP_TESTCARD_H)
|
||||
#define EASYCAP_TESTCARD_H
|
||||
|
||||
extern int easycap_debug;
|
||||
extern int easycap_gain;
|
||||
extern struct easycap_dongle easycapdc60_dongle[];
|
||||
|
||||
#endif /*EASYCAP_TESTCARD_H*/
|
Loading…
Reference in New Issue