summaryrefslogtreecommitdiff
path: root/drivers/media/video/em28xx/em28xx-audio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/em28xx/em28xx-audio.c')
-rw-r--r--drivers/media/video/em28xx/em28xx-audio.c54
1 files changed, 30 insertions, 24 deletions
diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c
index ac3292d7646c..15c03f0e69ad 100644
--- a/drivers/media/video/em28xx/em28xx-audio.c
+++ b/drivers/media/video/em28xx/em28xx-audio.c
@@ -62,7 +62,7 @@ static int em28xx_isoc_audio_deinit(struct em28xx *dev)
dprintk("Stopping isoc\n");
for (i = 0; i < EM28XX_AUDIO_BUFS; i++) {
- usb_kill_urb(dev->adev->urb[i]);
+ usb_unlink_urb(dev->adev->urb[i]);
usb_free_urb(dev->adev->urb[i]);
dev->adev->urb[i] = NULL;
}
@@ -75,7 +75,6 @@ static void em28xx_audio_isocirq(struct urb *urb)
struct em28xx *dev = urb->context;
int i;
unsigned int oldptr;
- unsigned long flags;
int period_elapsed = 0;
int status;
unsigned char *cp;
@@ -96,9 +95,21 @@ static void em28xx_audio_isocirq(struct urb *urb)
if (!length)
continue;
- spin_lock_irqsave(&dev->adev->slock, flags);
-
oldptr = dev->adev->hwptr_done_capture;
+ if (oldptr + length >= runtime->buffer_size) {
+ unsigned int cnt =
+ runtime->buffer_size - oldptr;
+ memcpy(runtime->dma_area + oldptr * stride, cp,
+ cnt * stride);
+ memcpy(runtime->dma_area, cp + cnt * stride,
+ length * stride - cnt * stride);
+ } else {
+ memcpy(runtime->dma_area + oldptr * stride, cp,
+ length * stride);
+ }
+
+ snd_pcm_stream_lock(substream);
+
dev->adev->hwptr_done_capture += length;
if (dev->adev->hwptr_done_capture >=
runtime->buffer_size)
@@ -113,19 +124,7 @@ static void em28xx_audio_isocirq(struct urb *urb)
period_elapsed = 1;
}
- spin_unlock_irqrestore(&dev->adev->slock, flags);
-
- if (oldptr + length >= runtime->buffer_size) {
- unsigned int cnt =
- runtime->buffer_size - oldptr;
- memcpy(runtime->dma_area + oldptr * stride, cp,
- cnt * stride);
- memcpy(runtime->dma_area, cp + cnt * stride,
- length * stride - cnt * stride);
- } else {
- memcpy(runtime->dma_area + oldptr * stride, cp,
- length * stride);
- }
+ snd_pcm_stream_unlock(substream);
}
if (period_elapsed)
snd_pcm_period_elapsed(substream);
@@ -425,11 +424,12 @@ static int em28xx_audio_init(struct em28xx *dev)
struct snd_pcm *pcm;
struct snd_card *card;
static int devnr;
- int ret, err;
+ int err;
- if (dev->has_audio_class) {
+ if (dev->has_alsa_audio != 1) {
/* This device does not support the extension (in this case
- the device is expecting the snd-usb-audio module */
+ the device is expecting the snd-usb-audio module or
+ doesn't have analog audio support at all) */
return 0;
}
@@ -450,7 +450,12 @@ static int em28xx_audio_init(struct em28xx *dev)
}
spin_lock_init(&adev->slock);
- ret = snd_pcm_new(card, "Em28xx Audio", 0, 0, 1, &pcm);
+ err = snd_pcm_new(card, "Em28xx Audio", 0, 0, 1, &pcm);
+ if (err < 0) {
+ snd_card_free(card);
+ return err;
+ }
+
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_em28xx_pcm_capture);
pcm->info_flags = 0;
pcm->private_data = dev;
@@ -462,7 +467,7 @@ static int em28xx_audio_init(struct em28xx *dev)
err = snd_card_register(card);
if (err < 0) {
snd_card_free(card);
- return -ENOMEM;
+ return err;
}
adev->sndcard = card;
adev->udev = dev->udev;
@@ -476,9 +481,10 @@ static int em28xx_audio_fini(struct em28xx *dev)
if (dev == NULL)
return 0;
- if (dev->has_audio_class) {
+ if (dev->has_alsa_audio != 1) {
/* This device does not support the extension (in this case
- the device is expecting the snd-usb-audio module */
+ the device is expecting the snd-usb-audio module or
+ doesn't have analog audio support at all) */
return 0;
}