[PATCH 128/961] staging/easycap: make OSS compilation optional instead of ALSA

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Tomas Winkler <tomas.winkler@xxxxxxxxx>

OSS is deprecated yet currently it is reported to be more stable
therefore we keep it but make it optional
Revert the conditional compilation:
	add  CONFIG_EASYCAP_OSS and kill EASYCAP_NEEDS_ALSA
move oss-only code from easycap_sound.c to easycap_sound_oss.c

Cc: Mike Thomas <rmthomas@xxxxxxxxxxx>
Signed-off-by: Tomas Winkler <tomas.winkler@xxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxx>
---
 drivers/staging/easycap/Kconfig             |   14 +-
 drivers/staging/easycap/Makefile            |   10 +-
 drivers/staging/easycap/easycap.h           |   25 +-
 drivers/staging/easycap/easycap_ioctl.c     |    4 +-
 drivers/staging/easycap/easycap_main.c      |   36 +-
 drivers/staging/easycap/easycap_sound.c     |  712 +--------------------------
 drivers/staging/easycap/easycap_sound_oss.c |  730 +++++++++++++++++++++++++++
 7 files changed, 789 insertions(+), 742 deletions(-)
 create mode 100644 drivers/staging/easycap/easycap_sound_oss.c

diff --git a/drivers/staging/easycap/Kconfig b/drivers/staging/easycap/Kconfig
index 4c1ad7e..5072cf8 100644
--- a/drivers/staging/easycap/Kconfig
+++ b/drivers/staging/easycap/Kconfig
@@ -1,6 +1,6 @@
 config EASYCAP
 	tristate "EasyCAP USB ID 05e1:0408 support"
-	depends on USB && VIDEO_DEV && SND
+	depends on USB && VIDEO_DEV && SOUND
 
 	---help---
 	  This is an integrated audio/video driver for EasyCAP cards with
@@ -15,6 +15,18 @@ config EASYCAP
 	  To compile this driver as a module, choose M here: the
 	  module will be called easycap
 
+config EASYCAP_OSS
+	bool "OSS (DEPRECATED)"
+	depends on EASYCAP && SOUND_OSS_CORE
+
+	---help---
+	  Say 'Y' if you prefer Open Sound System (OSS) interface
+
+	  This will disable Advanced Linux Sound Architecture (ALSA) binding.
+
+	  Once binding to ALSA interface will be stable this option will be
+          removed.
+
 config EASYCAP_DEBUG
 	bool "Enable EasyCAP driver debugging"
 	depends on EASYCAP
diff --git a/drivers/staging/easycap/Makefile b/drivers/staging/easycap/Makefile
index 226a779..a01ca11 100644
--- a/drivers/staging/easycap/Makefile
+++ b/drivers/staging/easycap/Makefile
@@ -1,5 +1,10 @@
-easycap-objs      := easycap_main.o easycap_low.o easycap_sound.o \
-		     easycap_ioctl.o easycap_settings.o easycap_testcard.o
+easycap-objs := easycap_main.o
+easycap-objs += easycap_low.o
+easycap-objs += easycap_ioctl.o
+easycap-objs += easycap_settings.o
+easycap-objs += easycap_testcard.o
+easycap-objs += easycap_sound.o
+easycap-$(CONFIG_EASYCAP_OSS) += easycap_sound_oss.o
 
 obj-$(CONFIG_EASYCAP)       += easycap.o
 
@@ -8,5 +13,4 @@ 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
 
diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h
index d751e75..55ff0d5 100644
--- a/drivers/staging/easycap/easycap.h
+++ b/drivers/staging/easycap/easycap.h
@@ -59,9 +59,9 @@
  */
 /*---------------------------------------------------------------------------*/
 #undef  EASYCAP_TESTCARD
-#if (!defined(EASYCAP_NEEDS_ALSA))
+#ifdef CONFIG_EASYCAP_OSS
 #undef  EASYCAP_TESTTONE
-#endif /*EASYCAP_NEEDS_ALSA*/
+#endif /* CONFIG_EASYCAP_OSS */
 /*---------------------------------------------------------------------------*/
 #include <linux/kernel.h>
 #include <linux/errno.h>
@@ -81,7 +81,7 @@
 #include <linux/delay.h>
 #include <linux/types.h>
 
-#if defined(EASYCAP_NEEDS_ALSA)
+#ifndef CONFIG_EASYCAP_OSS
 #include <linux/vmalloc.h>
 #include <linux/sound.h>
 #include <sound/core.h>
@@ -90,7 +90,7 @@
 #include <sound/info.h>
 #include <sound/initval.h>
 #include <sound/control.h>
-#endif /*EASYCAP_NEEDS_ALSA*/
+#endif /* !CONFIG_EASYCAP_OSS */
 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
 #if defined(EASYCAP_IS_VIDEODEV_CLIENT)
 #include <media/v4l2-dev.h>
@@ -445,7 +445,7 @@ __s16 oldaudio;
  *  ALSA
  */
 /*---------------------------------------------------------------------------*/
-#if defined(EASYCAP_NEEDS_ALSA)
+#ifndef CONFIG_EASYCAP_OSS
 	struct snd_pcm_hardware alsa_hardware;
 	struct snd_card *psnd_card;
 	struct snd_pcm *psnd_pcm;
@@ -453,7 +453,7 @@ __s16 oldaudio;
 	int dma_fill;
 	int dma_next;
 	int dma_read;
-#endif /*EASYCAP_NEEDS_ALSA*/
+#endif /* !CONFIG_EASYCAP_OSS */
 /*---------------------------------------------------------------------------*/
 /*
  *  SOUND PROPERTIES
@@ -537,7 +537,7 @@ int              adjust_volume(struct easycap *, int);
  *  AUDIO FUNCTION PROTOTYPES
  */
 /*---------------------------------------------------------------------------*/
-#if defined(EASYCAP_NEEDS_ALSA)
+#ifndef CONFIG_EASYCAP_OSS
 int		easycap_alsa_probe(struct easycap *);
 
 void            easycap_alsa_complete(struct urb *);
@@ -553,7 +553,7 @@ 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
+#else /* CONFIG_EASYCAP_OSS */
 void             easyoss_complete(struct urb *);
 ssize_t          easyoss_read(struct file *, char __user *, size_t, loff_t *);
 int              easyoss_open(struct inode *, struct file *);
@@ -564,7 +564,8 @@ int              easyoss_ioctl(struct inode *, struct file *, unsigned int,
 								unsigned long);
 unsigned int     easyoss_poll(struct file *, poll_table *);
 void             easyoss_delete(struct kref *);
-#endif /*EASYCAP_NEEDS_ALSA*/
+#endif /* !CONFIG_EASYCAP_OSS */
+
 int              easycap_sound_setup(struct easycap *);
 int              submit_audio_urbs(struct easycap *);
 int              kill_audio_urbs(struct easycap *);
@@ -715,13 +716,13 @@ extern struct easycap_format easycap_format[];
 extern struct v4l2_queryctrl easycap_control[];
 extern struct usb_driver easycap_usb_driver;
 extern struct easycap_dongle easycapdc60_dongle[];
-#if defined(EASYCAP_NEEDS_ALSA)
+#ifndef CONFIG_EASYCAP_OSS
 extern struct snd_pcm_ops easycap_alsa_ops;
 extern struct snd_pcm_hardware easycap_pcm_hardware;
 extern struct snd_card *psnd_card;
-#else
+#else /* CONFIG_EASYCAP_OSS */
 extern struct usb_class_driver easyoss_class;
 extern const struct file_operations easyoss_fops;
-#endif /*EASYCAP_NEEDS_ALSA*/
+#endif /* !CONFIG_EASYCAP_OSS */
 
 #endif /* !__EASYCAP_H__  */
diff --git a/drivers/staging/easycap/easycap_ioctl.c b/drivers/staging/easycap/easycap_ioctl.c
index 4389103..6995163 100644
--- a/drivers/staging/easycap/easycap_ioctl.c
+++ b/drivers/staging/easycap/easycap_ioctl.c
@@ -2517,7 +2517,7 @@ JOM(4, "unlocked easycapdc60_dongle[%i].mutex_video\n", kd);
 return 0;
 }
 /*****************************************************************************/
-#if !defined(EASYCAP_NEEDS_ALSA)
+#ifdef CONFIG_EASYCAP_OSS
 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
 #if ((defined(EASYCAP_IS_VIDEODEV_CLIENT)) || \
 	(defined(EASYCAP_NEEDS_UNLOCKED_IOCTL)))
@@ -2821,6 +2821,6 @@ default: {
 mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
 return 0;
 }
-#endif /*EASYCAP_NEEDS_ALSA*/
+#endif /* CONFIG_EASYCAP_OSS */
 /*****************************************************************************/
 
diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c
index cc1460b..d1d7a48 100644
--- a/drivers/staging/easycap/easycap_main.c
+++ b/drivers/staging/easycap/easycap_main.c
@@ -962,7 +962,7 @@ for (k = 0;  k < AUDIO_ISOC_BUFFER_MANY;  k++) {
 JOM(4, "easyoss_delete(): isoc audio buffers freed: %i pages\n",
 					m * (0x01 << AUDIO_ISOC_ORDER));
 /*---------------------------------------------------------------------------*/
-#if !defined(EASYCAP_NEEDS_ALSA)
+#ifdef CONFIG_EASYCAP_OSS
 JOM(4, "freeing audio buffers.\n");
 gone = 0;
 for (k = 0;  k < peasycap->audio_buffer_page_many;  k++) {
@@ -974,7 +974,7 @@ for (k = 0;  k < peasycap->audio_buffer_page_many;  k++) {
 	}
 }
 JOM(4, "easyoss_delete(): audio buffers freed: %i pages\n", gone);
-#endif /*!EASYCAP_NEEDS_ALSA*/
+#endif /* CONFIG_EASYCAP_OSS */
 /*---------------------------------------------------------------------------*/
 JOM(4, "freeing easycap structure.\n");
 allocation_video_urb    = peasycap->allocation_video_urb;
@@ -4350,7 +4350,7 @@ case 2: {
 	INIT_LIST_HEAD(&(peasycap->urb_audio_head));
 	peasycap->purb_audio_head = &(peasycap->urb_audio_head);
 
-#if !defined(EASYCAP_NEEDS_ALSA)
+#ifdef CONFIG_EASYCAP_OSS
 	JOM(4, "allocating an audio buffer\n");
 	JOM(4, ".... scattered over %i pages\n",
 					peasycap->audio_buffer_page_many);
@@ -4375,7 +4375,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*/
+#endif /* CONFIG_EASYCAP_OSS */
 /*---------------------------------------------------------------------------*/
 	JOM(4, "allocating %i isoc audio buffers of size %i\n",
 		AUDIO_ISOC_BUFFER_MANY, peasycap->audio_isoc_buffer_size);
@@ -4450,11 +4450,11 @@ case 2: {
 				"peasycap->audio_isoc_buffer[.].pgo;\n");
 			JOM(4, "  purb->transfer_buffer_length = %i;\n",
 					peasycap->audio_isoc_buffer_size);
-#if defined(EASYCAP_NEEDS_ALSA)
-			JOM(4, "  purb->complete = easycap_alsa_complete;\n");
-#else
+#ifdef CONFIG_EASYCAP_OSS
 			JOM(4, "  purb->complete = easyoss_complete;\n");
-#endif /*EASYCAP_NEEDS_ALSA*/
+#else /* CONFIG_EASYCAP_OSS */
+			JOM(4, "  purb->complete = easycap_alsa_complete;\n");
+#endif /* CONFIG_EASYCAP_OSS */
 			JOM(4, "  purb->context = peasycap;\n");
 			JOM(4, "  purb->start_frame = 0;\n");
 			JOM(4, "  purb->number_of_packets = %i;\n",
@@ -4477,11 +4477,11 @@ case 2: {
 		purb->transfer_buffer = peasycap->audio_isoc_buffer[k].pgo;
 		purb->transfer_buffer_length =
 					peasycap->audio_isoc_buffer_size;
-#if defined(EASYCAP_NEEDS_ALSA)
-		purb->complete = easycap_alsa_complete;
-#else
+#ifdef CONFIG_EASYCAP_OSS
 		purb->complete = easyoss_complete;
-#endif /*EASYCAP_NEEDS_ALSA*/
+#else /* CONFIG_EASYCAP_OSS */
+		purb->complete = easycap_alsa_complete;
+#endif /* CONFIG_EASYCAP_OSS */
 		purb->context = peasycap;
 		purb->start_frame = 0;
 		purb->number_of_packets = peasycap->audio_isoc_framesperdesc;
@@ -4504,7 +4504,7 @@ case 2: {
  *  THE AUDIO DEVICE CAN BE REGISTERED NOW, AS IT IS READY.
  */
 /*---------------------------------------------------------------------------*/
-#if defined(EASYCAP_NEEDS_ALSA)
+#ifndef CONFIG_EASYCAP_OSS
 	JOM(4, "initializing ALSA card\n");
 
 	rc = easycap_alsa_probe(peasycap);
@@ -4518,7 +4518,7 @@ case 2: {
 		(peasycap->registered_audio)++;
 	}
 
-#else /*EASYCAP_NEEDS_ALSA*/
+#else /* CONFIG_EASYCAP_OSS */
 	rc = usb_register_dev(pusb_interface, &easyoss_class);
 	if (0 != rc) {
 		SAY("ERROR: usb_register_dev() failed\n");
@@ -4536,7 +4536,7 @@ case 2: {
  */
 /*---------------------------------------------------------------------------*/
 	SAM("easyoss attached to minor #%d\n", pusb_interface->minor);
-#endif /*EASYCAP_NEEDS_ALSA*/
+#endif /* CONFIG_EASYCAP_OSS */
 
 	break;
 }
@@ -4774,7 +4774,7 @@ case 2: {
 		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)
+#ifndef CONFIG_EASYCAP_OSS
 
 
 
@@ -4786,12 +4786,12 @@ case 2: {
 	}
 
 
-#else /*EASYCAP_NEEDS_ALSA*/
+#else /* CONFIG_EASYCAP_OSS */
 	usb_deregister_dev(pusb_interface, &easyoss_class);
 	(peasycap->registered_audio)--;
 	JOM(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber);
 	SAM("easyoss detached from minor #%d\n", minor);
-#endif /*EASYCAP_NEEDS_ALSA*/
+#endif /* CONFIG_EASYCAP_OSS */
 
 	if (0 <= kd && DONGLE_MANY > kd) {
 		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
diff --git a/drivers/staging/easycap/easycap_sound.c b/drivers/staging/easycap/easycap_sound.c
index 05d9eed..07dd7aa 100644
--- a/drivers/staging/easycap/easycap_sound.c
+++ b/drivers/staging/easycap/easycap_sound.c
@@ -30,7 +30,7 @@
 
 #include "easycap.h"
 
-#if defined(EASYCAP_NEEDS_ALSA)
+#ifndef CONFIG_EASYCAP_OSS
 /*--------------------------------------------------------------------------*/
 /*
  *  PARAMETERS USED WHEN REGISTERING THE AUDIO INTERFACE
@@ -669,707 +669,7 @@ return vmalloc_to_page(pss->runtime->dma_area + offset);
 }
 /*****************************************************************************/
 
-#else /*!EASYCAP_NEEDS_ALSA*/
-
-/*****************************************************************************/
-/****************************                       **************************/
-/****************************   Open Sound System   **************************/
-/****************************                       **************************/
-/*****************************************************************************/
-/*--------------------------------------------------------------------------*/
-/*
- *  PARAMETERS USED WHEN REGISTERING THE AUDIO INTERFACE
- */
-/*--------------------------------------------------------------------------*/
-const struct file_operations easyoss_fops = {
-	.owner		= THIS_MODULE,
-	.open		= easyoss_open,
-	.release	= easyoss_release,
-#if defined(EASYCAP_NEEDS_UNLOCKED_IOCTL)
-	.unlocked_ioctl	= easyoss_ioctl_noinode,
-#else
-	.ioctl		= easyoss_ioctl,
-#endif /*EASYCAP_NEEDS_UNLOCKED_IOCTL*/
-	.read		= easyoss_read,
-	.llseek		= no_llseek,
-};
-struct usb_class_driver easyoss_class = {
-.name = "usb/easyoss%d",
-.fops = &easyoss_fops,
-.minor_base = USB_SKEL_MINOR_BASE,
-};
-/*****************************************************************************/
-/*---------------------------------------------------------------------------*/
-/*
- *  ON COMPLETION OF AN AUDIO URB ITS DATA IS COPIED TO THE AUDIO BUFFERS
- *  PROVIDED peasycap->audio_idle IS ZERO.  REGARDLESS OF THIS BEING TRUE,
- *  IT IS RESUBMITTED PROVIDED peasycap->audio_isoc_streaming IS NOT ZERO.
- */
-/*---------------------------------------------------------------------------*/
-void
-easyoss_complete(struct urb *purb)
-{
-struct easycap *peasycap;
-struct data_buffer *paudio_buffer;
-__u8 *p1, *p2;
-__s16 s16;
-int i, j, more, much, leap, rc;
-#if defined(UPSAMPLE)
-int k;
-__s16 oldaudio, newaudio, delta;
-#endif /*UPSAMPLE*/
-
-JOT(16, "\n");
-
-if (NULL == purb) {
-	SAY("ERROR: purb is NULL\n");
-	return;
-}
-peasycap = purb->context;
-if (NULL == peasycap) {
-	SAY("ERROR: peasycap is NULL\n");
-	return;
-}
-if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
-	SAY("ERROR: bad peasycap\n");
-	return;
-}
-much = 0;
-if (peasycap->audio_idle) {
-	JOM(16, "%i=audio_idle  %i=audio_isoc_streaming\n",
-			peasycap->audio_idle, peasycap->audio_isoc_streaming);
-	if (peasycap->audio_isoc_streaming) {
-		rc = usb_submit_urb(purb, GFP_ATOMIC);
-		if (rc) {
-			if (-ENODEV != rc && -ENOENT != rc) {
-				SAM("ERROR: while %i=audio_idle, "
-				    "usb_submit_urb() failed with rc: -%s: %d\n",
-					peasycap->audio_idle,
-					strerror(rc), rc);
-			}
-		}
-	}
-return;
-}
-/*---------------------------------------------------------------------------*/
-if (purb->status) {
-	if ((-ESHUTDOWN == purb->status) || (-ENOENT == purb->status)) {
-		JOM(16, "urb status -ESHUTDOWN or -ENOENT\n");
-		return;
-	}
-	SAM("ERROR: non-zero urb status: -%s: %d\n",
-		strerror(purb->status), purb->status);
-	goto resubmit;
-}
-/*---------------------------------------------------------------------------*/
-/*
- *  PROCEED HERE WHEN NO ERROR
- */
-/*---------------------------------------------------------------------------*/
-#if defined(UPSAMPLE)
-oldaudio = peasycap->oldaudio;
-#endif /*UPSAMPLE*/
-
-for (i = 0;  i < purb->number_of_packets; i++) {
-	if (!purb->iso_frame_desc[i].status) {
-
-		SAM("-%s\n", strerror(purb->iso_frame_desc[i].status));
-
-		more = purb->iso_frame_desc[i].actual_length;
-
-#if defined(TESTTONE)
-		if (!more)
-			more = purb->iso_frame_desc[i].length;
-#endif
-
-		if (!more)
-			peasycap->audio_mt++;
-		else {
-			if (peasycap->audio_mt) {
-				JOM(12, "%4i empty audio urb frames\n",
-							peasycap->audio_mt);
-				peasycap->audio_mt = 0;
-			}
-
-			p1 = (__u8 *)(purb->transfer_buffer +
-					purb->iso_frame_desc[i].offset);
-
-			leap = 0;
-			p1 += leap;
-			more -= leap;
-/*---------------------------------------------------------------------------*/
-/*
- *  COPY more BYTES FROM ISOC BUFFER TO AUDIO BUFFER,
- *  CONVERTING 8-BIT MONO TO 16-BIT SIGNED LITTLE-ENDIAN SAMPLES IF NECESSARY
- */
-/*---------------------------------------------------------------------------*/
-			while (more) {
-				if (0 > more) {
-					SAM("MISTAKE: more is negative\n");
-					return;
-				}
-				if (peasycap->audio_buffer_page_many <=
-							peasycap->audio_fill) {
-					SAM("ERROR: bad "
-						"peasycap->audio_fill\n");
-					return;
-				}
-
-				paudio_buffer = &peasycap->audio_buffer
-							[peasycap->audio_fill];
-				if (PAGE_SIZE < (paudio_buffer->pto -
-						paudio_buffer->pgo)) {
-					SAM("ERROR: bad paudio_buffer->pto\n");
-					return;
-				}
-				if (PAGE_SIZE == (paudio_buffer->pto -
-							paudio_buffer->pgo)) {
-
-#if defined(TESTTONE)
-					easyoss_testtone(peasycap,
-							peasycap->audio_fill);
-#endif /*TESTTONE*/
-
-					paudio_buffer->pto =
-							paudio_buffer->pgo;
-					(peasycap->audio_fill)++;
-					if (peasycap->
-						audio_buffer_page_many <=
-							peasycap->audio_fill)
-						peasycap->audio_fill = 0;
-
-					JOM(8, "bumped peasycap->"
-							"audio_fill to %i\n",
-							peasycap->audio_fill);
-
-					paudio_buffer = &peasycap->
-							audio_buffer
-							[peasycap->audio_fill];
-					paudio_buffer->pto =
-							paudio_buffer->pgo;
-
-					if (!(peasycap->audio_fill %
-						peasycap->
-						audio_pages_per_fragment)) {
-						JOM(12, "wakeup call on wq_"
-						"audio, %i=frag reading  %i"
-						"=fragment fill\n",
-						(peasycap->audio_read /
-						peasycap->
-						audio_pages_per_fragment),
-						(peasycap->audio_fill /
-						peasycap->
-						audio_pages_per_fragment));
-						wake_up_interruptible
-						(&(peasycap->wq_audio));
-					}
-				}
-
-				much = PAGE_SIZE - (int)(paudio_buffer->pto -
-							 paudio_buffer->pgo);
-
-				if (false == peasycap->microphone) {
-					if (much > more)
-						much = more;
-
-					memcpy(paudio_buffer->pto, p1, much);
-					p1 += much;
-					more -= much;
-				} else {
-#if defined(UPSAMPLE)
-					if (much % 16)
-						JOM(8, "MISTAKE? much"
-						" is not divisible by 16\n");
-					if (much > (16 *
-							more))
-						much = 16 *
-							more;
-					p2 = (__u8 *)paudio_buffer->pto;
-
-					for (j = 0;  j < (much/16);  j++) {
-						newaudio =  ((int) *p1) - 128;
-						newaudio = 128 *
-								newaudio;
-
-						delta = (newaudio - oldaudio)
-									/ 4;
-						s16 = oldaudio + delta;
-
-						for (k = 0;  k < 4;  k++) {
-							*p2 = (0x00FF & s16);
-							*(p2 + 1) = (0xFF00 &
-								s16) >> 8;
-							p2 += 2;
-							*p2 = (0x00FF & s16);
-							*(p2 + 1) = (0xFF00 &
-								s16) >> 8;
-							p2 += 2;
-
-							s16 += delta;
-						}
-						p1++;
-						more--;
-						oldaudio = s16;
-					}
-#else /*!UPSAMPLE*/
-					if (much > (2 * more))
-						much = 2 * more;
-					p2 = (__u8 *)paudio_buffer->pto;
-
-					for (j = 0;  j < (much / 2);  j++) {
-						s16 =  ((int) *p1) - 128;
-						s16 = 128 *
-								s16;
-						*p2 = (0x00FF & s16);
-						*(p2 + 1) = (0xFF00 & s16) >>
-									8;
-						p1++;  p2 += 2;
-						more--;
-					}
-#endif /*UPSAMPLE*/
-				}
-				(paudio_buffer->pto) += much;
-			}
-		}
-	} else {
-		JOM(12, "discarding audio samples because "
-			"%i=purb->iso_frame_desc[i].status\n",
-				purb->iso_frame_desc[i].status);
-	}
-
-#if defined(UPSAMPLE)
-peasycap->oldaudio = oldaudio;
-#endif /*UPSAMPLE*/
-
-}
-/*---------------------------------------------------------------------------*/
-/*
- *  RESUBMIT THIS URB
- */
-/*---------------------------------------------------------------------------*/
-resubmit:
-if (peasycap->audio_isoc_streaming) {
-	rc = usb_submit_urb(purb, GFP_ATOMIC);
-	if (0 != rc) {
-		if (-ENODEV != rc && -ENOENT != rc) {
-			SAM("ERROR: while %i=audio_idle, "
-				"usb_submit_urb() failed "
-				"with rc: -%s: %d\n", peasycap->audio_idle,
-				strerror(rc), rc);
-		}
-	}
-}
-return;
-}
-/*****************************************************************************/
-/*---------------------------------------------------------------------------*/
-/*
- *  THE AUDIO URBS ARE SUBMITTED AT THIS EARLY STAGE SO THAT IT IS POSSIBLE TO
- *  STREAM FROM /dev/easyoss1 WITH SIMPLE PROGRAMS SUCH AS cat WHICH DO NOT
- *  HAVE AN IOCTL INTERFACE.
- */
-/*---------------------------------------------------------------------------*/
-int
-easyoss_open(struct inode *inode, struct file *file)
-{
-struct usb_interface *pusb_interface;
-struct easycap *peasycap;
-int subminor;
-/*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");
-
-subminor = iminor(inode);
-
-pusb_interface = usb_find_interface(&easycap_usb_driver, subminor);
-if (NULL == pusb_interface) {
-	SAY("ERROR: pusb_interface is NULL\n");
-	SAY("ending unsuccessfully\n");
-	return -1;
-}
-peasycap = usb_get_intfdata(pusb_interface);
-if (NULL == peasycap) {
-	SAY("ERROR: peasycap is NULL\n");
-	SAY("ending unsuccessfully\n");
-	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;
-
-if (0 != easycap_sound_setup(peasycap)) {
-	;
-	;
-}
-return 0;
-}
-/*****************************************************************************/
-int
-easyoss_release(struct inode *inode, struct file *file)
-{
-struct easycap *peasycap;
-
-JOT(4, "begins\n");
-
-peasycap = file->private_data;
-if (NULL == peasycap) {
-	SAY("ERROR:  peasycap is NULL.\n");
-	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)) {
-	SAM("ERROR: kill_audio_urbs() failed\n");
-	return -EFAULT;
-}
-JOM(4, "ending successfully\n");
-return 0;
-}
-/*****************************************************************************/
-ssize_t
-easyoss_read(struct file *file, char __user *puserspacebuffer,
-						size_t kount, loff_t *poff)
-{
-struct timeval timeval;
-long long int above, below, mean;
-struct signed_div_result sdr;
-unsigned char *p0;
-long int kount1, more, rc, l0, lm;
-int fragment, kd;
-struct easycap *peasycap;
-struct data_buffer *pdata_buffer;
-size_t szret;
-
-/*---------------------------------------------------------------------------*/
-/*
- *  DO A BLOCKING READ TO TRANSFER DATA TO USER SPACE.
- *
- ******************************************************************************
- *****  N.B.  IF THIS FUNCTION RETURNS 0, NOTHING IS SEEN IN USER SPACE. ******
- *****        THIS CONDITION SIGNIFIES END-OF-FILE.                      ******
- ******************************************************************************
- */
-/*---------------------------------------------------------------------------*/
-
-JOT(8, "%5i=kount  %5i=*poff\n", (int)kount, (int)(*poff));
-
-if (NULL == file) {
-	SAY("ERROR:  file is NULL\n");
-	return -ERESTARTSYS;
-}
-peasycap = file->private_data;
-if (NULL == peasycap) {
-	SAY("ERROR in easyoss_read(): peasycap is NULL\n");
-	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) {
-	SAY("ERROR: peasycap->pusb_device is NULL\n");
-	return -EFAULT;
-}
-kd = isdongle(peasycap);
-if (0 <= kd && DONGLE_MANY > 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 easycapdc60_dongle[%i].mutex_audio\n", kd);
-/*---------------------------------------------------------------------------*/
-/*
- *  MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER peasycap,
- *  IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL.
- *  IF NECESSARY, BAIL OUT.
-*/
-/*---------------------------------------------------------------------------*/
-	if (kd != isdongle(peasycap))
-		return -ERESTARTSYS;
-	if (NULL == file) {
-		SAY("ERROR:  file is NULL\n");
-		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-		return -ERESTARTSYS;
-	}
-	peasycap = file->private_data;
-	if (NULL == peasycap) {
-		SAY("ERROR:  peasycap is NULL\n");
-		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-		return -ERESTARTSYS;
-	}
-	if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
-		SAY("ERROR: bad peasycap: 0x%08lX\n",
-						(unsigned long int) peasycap);
-		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-		return -ERESTARTSYS;
-	}
-	if (NULL == peasycap->pusb_device) {
-		SAM("ERROR: peasycap->pusb_device is NULL\n");
-		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-		return -ERESTARTSYS;
-	}
-} else {
-/*---------------------------------------------------------------------------*/
-/*
- *  IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap BEFORE THE
- *  ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL HAVE FAILED.  BAIL OUT.
-*/
-/*---------------------------------------------------------------------------*/
-	return -ERESTARTSYS;
-}
-/*---------------------------------------------------------------------------*/
-if (file->f_flags & O_NONBLOCK)
-	JOT(16, "NONBLOCK  kount=%i, *poff=%i\n", (int)kount, (int)(*poff));
-else
-	JOT(8, "BLOCKING  kount=%i, *poff=%i\n", (int)kount, (int)(*poff));
-
-if ((0 > peasycap->audio_read) ||
-		(peasycap->audio_buffer_page_many <= peasycap->audio_read)) {
-	SAM("ERROR: peasycap->audio_read out of range\n");
-	mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-	return -EFAULT;
-}
-pdata_buffer = &peasycap->audio_buffer[peasycap->audio_read];
-if ((struct data_buffer *)NULL == pdata_buffer) {
-	SAM("ERROR: pdata_buffer is NULL\n");
-	mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-	return -EFAULT;
-}
-JOM(12, "before wait, %i=frag read  %i=frag fill\n",
-		(peasycap->audio_read / peasycap->audio_pages_per_fragment),
-		(peasycap->audio_fill / peasycap->audio_pages_per_fragment));
-fragment = (peasycap->audio_read / peasycap->audio_pages_per_fragment);
-while ((fragment == (peasycap->audio_fill /
-				peasycap->audio_pages_per_fragment)) ||
-		(0 == (PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo)))) {
-	if (file->f_flags & O_NONBLOCK) {
-		JOM(16, "returning -EAGAIN as instructed\n");
-		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-		return -EAGAIN;
-	}
-	rc = wait_event_interruptible(peasycap->wq_audio,
-		(peasycap->audio_idle  || peasycap->audio_eof   ||
-		((fragment != (peasycap->audio_fill /
-				peasycap->audio_pages_per_fragment)) &&
-		(0 < (PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo))))));
-	if (0 != rc) {
-		SAM("aborted by signal\n");
-		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-		return -ERESTARTSYS;
-	}
-	if (peasycap->audio_eof) {
-		JOM(8, "returning 0 because  %i=audio_eof\n",
-							peasycap->audio_eof);
-		kill_audio_urbs(peasycap);
-		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-		return 0;
-	}
-	if (peasycap->audio_idle) {
-		JOM(16, "returning 0 because  %i=audio_idle\n",
-							peasycap->audio_idle);
-		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-		return 0;
-	}
-	if (!peasycap->audio_isoc_streaming) {
-		JOM(16, "returning 0 because audio urbs not streaming\n");
-		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-		return 0;
-	}
-}
-JOM(12, "after  wait, %i=frag read  %i=frag fill\n",
-		(peasycap->audio_read / peasycap->audio_pages_per_fragment),
-		(peasycap->audio_fill / peasycap->audio_pages_per_fragment));
-szret = (size_t)0;
-fragment = (peasycap->audio_read / peasycap->audio_pages_per_fragment);
-while (fragment == (peasycap->audio_read /
-				peasycap->audio_pages_per_fragment)) {
-	if (NULL == pdata_buffer->pgo) {
-		SAM("ERROR: pdata_buffer->pgo is NULL\n");
-		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-		return -EFAULT;
-	}
-	if (NULL == pdata_buffer->pto) {
-		SAM("ERROR: pdata_buffer->pto is NULL\n");
-		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-		return -EFAULT;
-	}
-	kount1 = PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo);
-	if (0 > kount1) {
-		SAM("MISTAKE: kount1 is negative\n");
-		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-		return -ERESTARTSYS;
-	}
-	if (!kount1) {
-		(peasycap->audio_read)++;
-		if (peasycap->audio_buffer_page_many <= peasycap->audio_read)
-			peasycap->audio_read = 0;
-		JOM(12, "bumped peasycap->audio_read to %i\n",
-						peasycap->audio_read);
-
-		if (fragment != (peasycap->audio_read /
-					peasycap->audio_pages_per_fragment))
-			break;
-
-		if ((0 > peasycap->audio_read) ||
-			(peasycap->audio_buffer_page_many <=
-					peasycap->audio_read)) {
-			SAM("ERROR: peasycap->audio_read out of range\n");
-			mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-			return -EFAULT;
-		}
-		pdata_buffer = &peasycap->audio_buffer[peasycap->audio_read];
-		if ((struct data_buffer *)NULL == pdata_buffer) {
-			SAM("ERROR: pdata_buffer is NULL\n");
-			mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-			return -EFAULT;
-		}
-		if (NULL == pdata_buffer->pgo) {
-			SAM("ERROR: pdata_buffer->pgo is NULL\n");
-			mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-			return -EFAULT;
-		}
-		if (NULL == pdata_buffer->pto) {
-			SAM("ERROR: pdata_buffer->pto is NULL\n");
-			mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-			return -EFAULT;
-		}
-		kount1 = PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo);
-	}
-	JOM(12, "ready  to send %li bytes\n", (long int) kount1);
-	JOM(12, "still  to send %li bytes\n", (long int) kount);
-	more = kount1;
-	if (more > kount)
-		more = kount;
-	JOM(12, "agreed to send %li bytes from page %i\n",
-						more, peasycap->audio_read);
-	if (!more)
-		break;
-
-/*---------------------------------------------------------------------------*/
-/*
- *  ACCUMULATE DYNAMIC-RANGE INFORMATION
- */
-/*---------------------------------------------------------------------------*/
-	p0 = (unsigned char *)pdata_buffer->pgo;  l0 = 0;  lm = more/2;
-	while (l0 < lm) {
-		SUMMER(p0, &peasycap->audio_sample, &peasycap->audio_niveau,
-				&peasycap->audio_square);  l0++;  p0 += 2;
-	}
-/*---------------------------------------------------------------------------*/
-	rc = copy_to_user(puserspacebuffer, pdata_buffer->pto, more);
-	if (0 != rc) {
-		SAM("ERROR: copy_to_user() returned %li\n", rc);
-		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-		return -EFAULT;
-	}
-	*poff += (loff_t)more;
-	szret += (size_t)more;
-	pdata_buffer->pto += more;
-	puserspacebuffer += more;
-	kount -= (size_t)more;
-}
-JOM(12, "after  read, %i=frag read  %i=frag fill\n",
-		(peasycap->audio_read / peasycap->audio_pages_per_fragment),
-		(peasycap->audio_fill / peasycap->audio_pages_per_fragment));
-if (kount < 0) {
-	SAM("MISTAKE:  %li=kount  %li=szret\n",
-					(long int)kount, (long int)szret);
-}
-/*---------------------------------------------------------------------------*/
-/*
- *  CALCULATE DYNAMIC RANGE FOR (VAPOURWARE) AUTOMATIC VOLUME CONTROL
- */
-/*---------------------------------------------------------------------------*/
-if (peasycap->audio_sample) {
-	below = peasycap->audio_sample;
-	above = peasycap->audio_square;
-	sdr = signed_div(above, below);
-	above = sdr.quotient;
-	mean = peasycap->audio_niveau;
-	sdr = signed_div(mean, peasycap->audio_sample);
-
-	JOM(8, "%8lli=mean  %8lli=meansquare after %lli samples, =>\n",
-				sdr.quotient, above, peasycap->audio_sample);
-
-	sdr = signed_div(above, 32768);
-	JOM(8, "audio dynamic range is roughly %lli\n", sdr.quotient);
-}
-/*---------------------------------------------------------------------------*/
-/*
- *  UPDATE THE AUDIO CLOCK
- */
-/*---------------------------------------------------------------------------*/
-do_gettimeofday(&timeval);
-if (!peasycap->timeval1.tv_sec) {
-	peasycap->audio_bytes = 0;
-	peasycap->timeval3 = timeval;
-	peasycap->timeval1 = peasycap->timeval3;
-	sdr.quotient = 192000;
-} else {
-	peasycap->audio_bytes += (long long int) szret;
-	below = ((long long int)(1000000)) *
-		((long long int)(timeval.tv_sec  -
-						peasycap->timeval3.tv_sec)) +
-		(long long int)(timeval.tv_usec - peasycap->timeval3.tv_usec);
-	above = 1000000 * ((long long int) peasycap->audio_bytes);
-
-	if (below)
-		sdr = signed_div(above, below);
-	else
-		sdr.quotient = 192000;
-}
-JOM(8, "audio streaming at %lli bytes/second\n", sdr.quotient);
-peasycap->dnbydt = sdr.quotient;
-
-mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-JOM(4, "unlocked easycapdc60_dongle[%i].mutex_audio\n", kd);
-JOM(8, "returning %li\n", (long int)szret);
-return szret;
-}
-/*****************************************************************************/
-
-#endif /*!EASYCAP_NEEDS_ALSA*/
+#endif /*! CONFIG_EASYCAP_OSS */
 
 /*****************************************************************************/
 /*****************************************************************************/
@@ -1484,11 +784,11 @@ if (!peasycap->audio_isoc_streaming) {
 					peasycap->audio_isoc_buffer[isbuf].pgo;
 				purb->transfer_buffer_length =
 					peasycap->audio_isoc_buffer_size;
-#if defined(EASYCAP_NEEDS_ALSA)
-				purb->complete = easycap_alsa_complete;
-#else
+#ifdef CONFIG_EASYCAP_OSS
 				purb->complete = easyoss_complete;
-#endif /*EASYCAP_NEEDS_ALSA*/
+#else /* CONFIG_EASYCAP_OSS */
+				purb->complete = easycap_alsa_complete;
+#endif /* CONFIG_EASYCAP_OSS */
 				purb->context = peasycap;
 				purb->start_frame = 0;
 				purb->number_of_packets =
diff --git a/drivers/staging/easycap/easycap_sound_oss.c b/drivers/staging/easycap/easycap_sound_oss.c
new file mode 100644
index 0000000..3f85cc3
--- /dev/null
+++ b/drivers/staging/easycap/easycap_sound_oss.c
@@ -0,0 +1,730 @@
+/******************************************************************************
+*                                                                             *
+*  easycap_sound.c                                                            *
+*                                                                             *
+*  Audio driver for EasyCAP USB2.0 Video Capture Device DC60                  *
+*                                                                             *
+*                                                                             *
+******************************************************************************/
+/*
+ *
+ *  Copyright (C) 2010 R.M. Thomas  <rmthomas@xxxxxxxxxxx>
+ *
+ *
+ *  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
+ *
+*/
+/*****************************************************************************/
+
+#include "easycap.h"
+
+/*****************************************************************************/
+/****************************                       **************************/
+/****************************   Open Sound System   **************************/
+/****************************                       **************************/
+/*****************************************************************************/
+/*--------------------------------------------------------------------------*/
+/*
+ *  PARAMETERS USED WHEN REGISTERING THE AUDIO INTERFACE
+ */
+/*--------------------------------------------------------------------------*/
+const struct file_operations easyoss_fops = {
+	.owner		= THIS_MODULE,
+	.open		= easyoss_open,
+	.release	= easyoss_release,
+#if defined(EASYCAP_NEEDS_UNLOCKED_IOCTL)
+	.unlocked_ioctl	= easyoss_ioctl_noinode,
+#else
+	.ioctl		= easyoss_ioctl,
+#endif /*EASYCAP_NEEDS_UNLOCKED_IOCTL*/
+	.read		= easyoss_read,
+	.llseek		= no_llseek,
+};
+struct usb_class_driver easyoss_class = {
+.name = "usb/easyoss%d",
+.fops = &easyoss_fops,
+.minor_base = USB_SKEL_MINOR_BASE,
+};
+/*****************************************************************************/
+/*---------------------------------------------------------------------------*/
+/*
+ *  ON COMPLETION OF AN AUDIO URB ITS DATA IS COPIED TO THE AUDIO BUFFERS
+ *  PROVIDED peasycap->audio_idle IS ZERO.  REGARDLESS OF THIS BEING TRUE,
+ *  IT IS RESUBMITTED PROVIDED peasycap->audio_isoc_streaming IS NOT ZERO.
+ */
+/*---------------------------------------------------------------------------*/
+void
+easyoss_complete(struct urb *purb)
+{
+struct easycap *peasycap;
+struct data_buffer *paudio_buffer;
+__u8 *p1, *p2;
+__s16 s16;
+int i, j, more, much, leap, rc;
+#if defined(UPSAMPLE)
+int k;
+__s16 oldaudio, newaudio, delta;
+#endif /*UPSAMPLE*/
+
+JOT(16, "\n");
+
+if (NULL == purb) {
+	SAY("ERROR: purb is NULL\n");
+	return;
+}
+peasycap = purb->context;
+if (NULL == peasycap) {
+	SAY("ERROR: peasycap is NULL\n");
+	return;
+}
+if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
+	SAY("ERROR: bad peasycap\n");
+	return;
+}
+much = 0;
+if (peasycap->audio_idle) {
+	JOM(16, "%i=audio_idle  %i=audio_isoc_streaming\n",
+			peasycap->audio_idle, peasycap->audio_isoc_streaming);
+	if (peasycap->audio_isoc_streaming) {
+		rc = usb_submit_urb(purb, GFP_ATOMIC);
+		if (rc) {
+			if (-ENODEV != rc && -ENOENT != rc) {
+				SAM("ERROR: while %i=audio_idle, "
+				    "usb_submit_urb() failed with rc: -%s: %d\n",
+					peasycap->audio_idle,
+					strerror(rc), rc);
+			}
+		}
+	}
+return;
+}
+/*---------------------------------------------------------------------------*/
+if (purb->status) {
+	if ((-ESHUTDOWN == purb->status) || (-ENOENT == purb->status)) {
+		JOM(16, "urb status -ESHUTDOWN or -ENOENT\n");
+		return;
+	}
+	SAM("ERROR: non-zero urb status: -%s: %d\n",
+		strerror(purb->status), purb->status);
+	goto resubmit;
+}
+/*---------------------------------------------------------------------------*/
+/*
+ *  PROCEED HERE WHEN NO ERROR
+ */
+/*---------------------------------------------------------------------------*/
+#if defined(UPSAMPLE)
+oldaudio = peasycap->oldaudio;
+#endif /*UPSAMPLE*/
+
+for (i = 0;  i < purb->number_of_packets; i++) {
+	if (!purb->iso_frame_desc[i].status) {
+
+		SAM("-%s\n", strerror(purb->iso_frame_desc[i].status));
+
+		more = purb->iso_frame_desc[i].actual_length;
+
+#if defined(TESTTONE)
+		if (!more)
+			more = purb->iso_frame_desc[i].length;
+#endif
+
+		if (!more)
+			peasycap->audio_mt++;
+		else {
+			if (peasycap->audio_mt) {
+				JOM(12, "%4i empty audio urb frames\n",
+							peasycap->audio_mt);
+				peasycap->audio_mt = 0;
+			}
+
+			p1 = (__u8 *)(purb->transfer_buffer +
+					purb->iso_frame_desc[i].offset);
+
+			leap = 0;
+			p1 += leap;
+			more -= leap;
+/*---------------------------------------------------------------------------*/
+/*
+ *  COPY more BYTES FROM ISOC BUFFER TO AUDIO BUFFER,
+ *  CONVERTING 8-BIT MONO TO 16-BIT SIGNED LITTLE-ENDIAN SAMPLES IF NECESSARY
+ */
+/*---------------------------------------------------------------------------*/
+			while (more) {
+				if (0 > more) {
+					SAM("MISTAKE: more is negative\n");
+					return;
+				}
+				if (peasycap->audio_buffer_page_many <=
+							peasycap->audio_fill) {
+					SAM("ERROR: bad "
+						"peasycap->audio_fill\n");
+					return;
+				}
+
+				paudio_buffer = &peasycap->audio_buffer
+							[peasycap->audio_fill];
+				if (PAGE_SIZE < (paudio_buffer->pto -
+						paudio_buffer->pgo)) {
+					SAM("ERROR: bad paudio_buffer->pto\n");
+					return;
+				}
+				if (PAGE_SIZE == (paudio_buffer->pto -
+							paudio_buffer->pgo)) {
+
+#if defined(TESTTONE)
+					easyoss_testtone(peasycap,
+							peasycap->audio_fill);
+#endif /*TESTTONE*/
+
+					paudio_buffer->pto =
+							paudio_buffer->pgo;
+					(peasycap->audio_fill)++;
+					if (peasycap->
+						audio_buffer_page_many <=
+							peasycap->audio_fill)
+						peasycap->audio_fill = 0;
+
+					JOM(8, "bumped peasycap->"
+							"audio_fill to %i\n",
+							peasycap->audio_fill);
+
+					paudio_buffer = &peasycap->
+							audio_buffer
+							[peasycap->audio_fill];
+					paudio_buffer->pto =
+							paudio_buffer->pgo;
+
+					if (!(peasycap->audio_fill %
+						peasycap->
+						audio_pages_per_fragment)) {
+						JOM(12, "wakeup call on wq_"
+						"audio, %i=frag reading  %i"
+						"=fragment fill\n",
+						(peasycap->audio_read /
+						peasycap->
+						audio_pages_per_fragment),
+						(peasycap->audio_fill /
+						peasycap->
+						audio_pages_per_fragment));
+						wake_up_interruptible
+						(&(peasycap->wq_audio));
+					}
+				}
+
+				much = PAGE_SIZE - (int)(paudio_buffer->pto -
+							 paudio_buffer->pgo);
+
+				if (false == peasycap->microphone) {
+					if (much > more)
+						much = more;
+
+					memcpy(paudio_buffer->pto, p1, much);
+					p1 += much;
+					more -= much;
+				} else {
+#if defined(UPSAMPLE)
+					if (much % 16)
+						JOM(8, "MISTAKE? much"
+						" is not divisible by 16\n");
+					if (much > (16 *
+							more))
+						much = 16 *
+							more;
+					p2 = (__u8 *)paudio_buffer->pto;
+
+					for (j = 0;  j < (much/16);  j++) {
+						newaudio =  ((int) *p1) - 128;
+						newaudio = 128 *
+								newaudio;
+
+						delta = (newaudio - oldaudio)
+									/ 4;
+						s16 = oldaudio + delta;
+
+						for (k = 0;  k < 4;  k++) {
+							*p2 = (0x00FF & s16);
+							*(p2 + 1) = (0xFF00 &
+								s16) >> 8;
+							p2 += 2;
+							*p2 = (0x00FF & s16);
+							*(p2 + 1) = (0xFF00 &
+								s16) >> 8;
+							p2 += 2;
+
+							s16 += delta;
+						}
+						p1++;
+						more--;
+						oldaudio = s16;
+					}
+#else /*!UPSAMPLE*/
+					if (much > (2 * more))
+						much = 2 * more;
+					p2 = (__u8 *)paudio_buffer->pto;
+
+					for (j = 0;  j < (much / 2);  j++) {
+						s16 =  ((int) *p1) - 128;
+						s16 = 128 *
+								s16;
+						*p2 = (0x00FF & s16);
+						*(p2 + 1) = (0xFF00 & s16) >>
+									8;
+						p1++;  p2 += 2;
+						more--;
+					}
+#endif /*UPSAMPLE*/
+				}
+				(paudio_buffer->pto) += much;
+			}
+		}
+	} else {
+		JOM(12, "discarding audio samples because "
+			"%i=purb->iso_frame_desc[i].status\n",
+				purb->iso_frame_desc[i].status);
+	}
+
+#if defined(UPSAMPLE)
+peasycap->oldaudio = oldaudio;
+#endif /*UPSAMPLE*/
+
+}
+/*---------------------------------------------------------------------------*/
+/*
+ *  RESUBMIT THIS URB
+ */
+/*---------------------------------------------------------------------------*/
+resubmit:
+if (peasycap->audio_isoc_streaming) {
+	rc = usb_submit_urb(purb, GFP_ATOMIC);
+	if (0 != rc) {
+		if (-ENODEV != rc && -ENOENT != rc) {
+			SAM("ERROR: while %i=audio_idle, "
+				"usb_submit_urb() failed "
+				"with rc: -%s: %d\n", peasycap->audio_idle,
+				strerror(rc), rc);
+		}
+	}
+}
+return;
+}
+/*****************************************************************************/
+/*---------------------------------------------------------------------------*/
+/*
+ *  THE AUDIO URBS ARE SUBMITTED AT THIS EARLY STAGE SO THAT IT IS POSSIBLE TO
+ *  STREAM FROM /dev/easyoss1 WITH SIMPLE PROGRAMS SUCH AS cat WHICH DO NOT
+ *  HAVE AN IOCTL INTERFACE.
+ */
+/*---------------------------------------------------------------------------*/
+int
+easyoss_open(struct inode *inode, struct file *file)
+{
+struct usb_interface *pusb_interface;
+struct easycap *peasycap;
+int subminor;
+/*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");
+
+subminor = iminor(inode);
+
+pusb_interface = usb_find_interface(&easycap_usb_driver, subminor);
+if (NULL == pusb_interface) {
+	SAY("ERROR: pusb_interface is NULL\n");
+	SAY("ending unsuccessfully\n");
+	return -1;
+}
+peasycap = usb_get_intfdata(pusb_interface);
+if (NULL == peasycap) {
+	SAY("ERROR: peasycap is NULL\n");
+	SAY("ending unsuccessfully\n");
+	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;
+
+if (0 != easycap_sound_setup(peasycap)) {
+	;
+	;
+}
+return 0;
+}
+/*****************************************************************************/
+int
+easyoss_release(struct inode *inode, struct file *file)
+{
+struct easycap *peasycap;
+
+JOT(4, "begins\n");
+
+peasycap = file->private_data;
+if (NULL == peasycap) {
+	SAY("ERROR:  peasycap is NULL.\n");
+	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)) {
+	SAM("ERROR: kill_audio_urbs() failed\n");
+	return -EFAULT;
+}
+JOM(4, "ending successfully\n");
+return 0;
+}
+/*****************************************************************************/
+ssize_t
+easyoss_read(struct file *file, char __user *puserspacebuffer,
+						size_t kount, loff_t *poff)
+{
+struct timeval timeval;
+long long int above, below, mean;
+struct signed_div_result sdr;
+unsigned char *p0;
+long int kount1, more, rc, l0, lm;
+int fragment, kd;
+struct easycap *peasycap;
+struct data_buffer *pdata_buffer;
+size_t szret;
+
+/*---------------------------------------------------------------------------*/
+/*
+ *  DO A BLOCKING READ TO TRANSFER DATA TO USER SPACE.
+ *
+ ******************************************************************************
+ *****  N.B.  IF THIS FUNCTION RETURNS 0, NOTHING IS SEEN IN USER SPACE. ******
+ *****        THIS CONDITION SIGNIFIES END-OF-FILE.                      ******
+ ******************************************************************************
+ */
+/*---------------------------------------------------------------------------*/
+
+JOT(8, "%5i=kount  %5i=*poff\n", (int)kount, (int)(*poff));
+
+if (NULL == file) {
+	SAY("ERROR:  file is NULL\n");
+	return -ERESTARTSYS;
+}
+peasycap = file->private_data;
+if (NULL == peasycap) {
+	SAY("ERROR in easyoss_read(): peasycap is NULL\n");
+	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) {
+	SAY("ERROR: peasycap->pusb_device is NULL\n");
+	return -EFAULT;
+}
+kd = isdongle(peasycap);
+if (0 <= kd && DONGLE_MANY > 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 easycapdc60_dongle[%i].mutex_audio\n", kd);
+/*---------------------------------------------------------------------------*/
+/*
+ *  MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER peasycap,
+ *  IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL.
+ *  IF NECESSARY, BAIL OUT.
+*/
+/*---------------------------------------------------------------------------*/
+	if (kd != isdongle(peasycap))
+		return -ERESTARTSYS;
+	if (NULL == file) {
+		SAY("ERROR:  file is NULL\n");
+		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+		return -ERESTARTSYS;
+	}
+	peasycap = file->private_data;
+	if (NULL == peasycap) {
+		SAY("ERROR:  peasycap is NULL\n");
+		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+		return -ERESTARTSYS;
+	}
+	if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
+		SAY("ERROR: bad peasycap: 0x%08lX\n",
+						(unsigned long int) peasycap);
+		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+		return -ERESTARTSYS;
+	}
+	if (NULL == peasycap->pusb_device) {
+		SAM("ERROR: peasycap->pusb_device is NULL\n");
+		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+		return -ERESTARTSYS;
+	}
+} else {
+/*---------------------------------------------------------------------------*/
+/*
+ *  IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap BEFORE THE
+ *  ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL HAVE FAILED.  BAIL OUT.
+*/
+/*---------------------------------------------------------------------------*/
+	return -ERESTARTSYS;
+}
+/*---------------------------------------------------------------------------*/
+if (file->f_flags & O_NONBLOCK)
+	JOT(16, "NONBLOCK  kount=%i, *poff=%i\n", (int)kount, (int)(*poff));
+else
+	JOT(8, "BLOCKING  kount=%i, *poff=%i\n", (int)kount, (int)(*poff));
+
+if ((0 > peasycap->audio_read) ||
+		(peasycap->audio_buffer_page_many <= peasycap->audio_read)) {
+	SAM("ERROR: peasycap->audio_read out of range\n");
+	mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+	return -EFAULT;
+}
+pdata_buffer = &peasycap->audio_buffer[peasycap->audio_read];
+if ((struct data_buffer *)NULL == pdata_buffer) {
+	SAM("ERROR: pdata_buffer is NULL\n");
+	mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+	return -EFAULT;
+}
+JOM(12, "before wait, %i=frag read  %i=frag fill\n",
+		(peasycap->audio_read / peasycap->audio_pages_per_fragment),
+		(peasycap->audio_fill / peasycap->audio_pages_per_fragment));
+fragment = (peasycap->audio_read / peasycap->audio_pages_per_fragment);
+while ((fragment == (peasycap->audio_fill /
+				peasycap->audio_pages_per_fragment)) ||
+		(0 == (PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo)))) {
+	if (file->f_flags & O_NONBLOCK) {
+		JOM(16, "returning -EAGAIN as instructed\n");
+		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+		return -EAGAIN;
+	}
+	rc = wait_event_interruptible(peasycap->wq_audio,
+		(peasycap->audio_idle  || peasycap->audio_eof   ||
+		((fragment != (peasycap->audio_fill /
+				peasycap->audio_pages_per_fragment)) &&
+		(0 < (PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo))))));
+	if (0 != rc) {
+		SAM("aborted by signal\n");
+		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+		return -ERESTARTSYS;
+	}
+	if (peasycap->audio_eof) {
+		JOM(8, "returning 0 because  %i=audio_eof\n",
+							peasycap->audio_eof);
+		kill_audio_urbs(peasycap);
+		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+		return 0;
+	}
+	if (peasycap->audio_idle) {
+		JOM(16, "returning 0 because  %i=audio_idle\n",
+							peasycap->audio_idle);
+		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+		return 0;
+	}
+	if (!peasycap->audio_isoc_streaming) {
+		JOM(16, "returning 0 because audio urbs not streaming\n");
+		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+		return 0;
+	}
+}
+JOM(12, "after  wait, %i=frag read  %i=frag fill\n",
+		(peasycap->audio_read / peasycap->audio_pages_per_fragment),
+		(peasycap->audio_fill / peasycap->audio_pages_per_fragment));
+szret = (size_t)0;
+fragment = (peasycap->audio_read / peasycap->audio_pages_per_fragment);
+while (fragment == (peasycap->audio_read /
+				peasycap->audio_pages_per_fragment)) {
+	if (NULL == pdata_buffer->pgo) {
+		SAM("ERROR: pdata_buffer->pgo is NULL\n");
+		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+		return -EFAULT;
+	}
+	if (NULL == pdata_buffer->pto) {
+		SAM("ERROR: pdata_buffer->pto is NULL\n");
+		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+		return -EFAULT;
+	}
+	kount1 = PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo);
+	if (0 > kount1) {
+		SAM("MISTAKE: kount1 is negative\n");
+		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+		return -ERESTARTSYS;
+	}
+	if (!kount1) {
+		(peasycap->audio_read)++;
+		if (peasycap->audio_buffer_page_many <= peasycap->audio_read)
+			peasycap->audio_read = 0;
+		JOM(12, "bumped peasycap->audio_read to %i\n",
+						peasycap->audio_read);
+
+		if (fragment != (peasycap->audio_read /
+					peasycap->audio_pages_per_fragment))
+			break;
+
+		if ((0 > peasycap->audio_read) ||
+			(peasycap->audio_buffer_page_many <=
+					peasycap->audio_read)) {
+			SAM("ERROR: peasycap->audio_read out of range\n");
+			mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+			return -EFAULT;
+		}
+		pdata_buffer = &peasycap->audio_buffer[peasycap->audio_read];
+		if ((struct data_buffer *)NULL == pdata_buffer) {
+			SAM("ERROR: pdata_buffer is NULL\n");
+			mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+			return -EFAULT;
+		}
+		if (NULL == pdata_buffer->pgo) {
+			SAM("ERROR: pdata_buffer->pgo is NULL\n");
+			mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+			return -EFAULT;
+		}
+		if (NULL == pdata_buffer->pto) {
+			SAM("ERROR: pdata_buffer->pto is NULL\n");
+			mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+			return -EFAULT;
+		}
+		kount1 = PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo);
+	}
+	JOM(12, "ready  to send %li bytes\n", (long int) kount1);
+	JOM(12, "still  to send %li bytes\n", (long int) kount);
+	more = kount1;
+	if (more > kount)
+		more = kount;
+	JOM(12, "agreed to send %li bytes from page %i\n",
+						more, peasycap->audio_read);
+	if (!more)
+		break;
+
+/*---------------------------------------------------------------------------*/
+/*
+ *  ACCUMULATE DYNAMIC-RANGE INFORMATION
+ */
+/*---------------------------------------------------------------------------*/
+	p0 = (unsigned char *)pdata_buffer->pgo;  l0 = 0;  lm = more/2;
+	while (l0 < lm) {
+		SUMMER(p0, &peasycap->audio_sample, &peasycap->audio_niveau,
+				&peasycap->audio_square);  l0++;  p0 += 2;
+	}
+/*---------------------------------------------------------------------------*/
+	rc = copy_to_user(puserspacebuffer, pdata_buffer->pto, more);
+	if (0 != rc) {
+		SAM("ERROR: copy_to_user() returned %li\n", rc);
+		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+		return -EFAULT;
+	}
+	*poff += (loff_t)more;
+	szret += (size_t)more;
+	pdata_buffer->pto += more;
+	puserspacebuffer += more;
+	kount -= (size_t)more;
+}
+JOM(12, "after  read, %i=frag read  %i=frag fill\n",
+		(peasycap->audio_read / peasycap->audio_pages_per_fragment),
+		(peasycap->audio_fill / peasycap->audio_pages_per_fragment));
+if (kount < 0) {
+	SAM("MISTAKE:  %li=kount  %li=szret\n",
+					(long int)kount, (long int)szret);
+}
+/*---------------------------------------------------------------------------*/
+/*
+ *  CALCULATE DYNAMIC RANGE FOR (VAPOURWARE) AUTOMATIC VOLUME CONTROL
+ */
+/*---------------------------------------------------------------------------*/
+if (peasycap->audio_sample) {
+	below = peasycap->audio_sample;
+	above = peasycap->audio_square;
+	sdr = signed_div(above, below);
+	above = sdr.quotient;
+	mean = peasycap->audio_niveau;
+	sdr = signed_div(mean, peasycap->audio_sample);
+
+	JOM(8, "%8lli=mean  %8lli=meansquare after %lli samples, =>\n",
+				sdr.quotient, above, peasycap->audio_sample);
+
+	sdr = signed_div(above, 32768);
+	JOM(8, "audio dynamic range is roughly %lli\n", sdr.quotient);
+}
+/*---------------------------------------------------------------------------*/
+/*
+ *  UPDATE THE AUDIO CLOCK
+ */
+/*---------------------------------------------------------------------------*/
+do_gettimeofday(&timeval);
+if (!peasycap->timeval1.tv_sec) {
+	peasycap->audio_bytes = 0;
+	peasycap->timeval3 = timeval;
+	peasycap->timeval1 = peasycap->timeval3;
+	sdr.quotient = 192000;
+} else {
+	peasycap->audio_bytes += (long long int) szret;
+	below = ((long long int)(1000000)) *
+		((long long int)(timeval.tv_sec  -
+						peasycap->timeval3.tv_sec)) +
+		(long long int)(timeval.tv_usec - peasycap->timeval3.tv_usec);
+	above = 1000000 * ((long long int) peasycap->audio_bytes);
+
+	if (below)
+		sdr = signed_div(above, below);
+	else
+		sdr.quotient = 192000;
+}
+JOM(8, "audio streaming at %lli bytes/second\n", sdr.quotient);
+peasycap->dnbydt = sdr.quotient;
+
+mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+JOM(4, "unlocked easycapdc60_dongle[%i].mutex_audio\n", kd);
+JOM(8, "returning %li\n", (long int)szret);
+return szret;
+}
+/*****************************************************************************/
+
-- 
1.7.4.1

_______________________________________________
devel mailing list
devel@xxxxxxxxxxxxxxxxxxxxxx
http://driverdev.linuxdriverproject.org/mailman/listinfo/devel


[Index of Archives]     [Linux Driver Backports]     [DMA Engine]     [Linux GPIO]     [Linux SPI]     [Video for Linux]     [Linux USB Devel]     [Linux Coverity]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux