aboutsummaryrefslogtreecommitdiffstats
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.c33
1 files changed, 16 insertions, 17 deletions
diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c
index ac3292d7646..7a8d49ef646 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)
62 62
63 dprintk("Stopping isoc\n"); 63 dprintk("Stopping isoc\n");
64 for (i = 0; i < EM28XX_AUDIO_BUFS; i++) { 64 for (i = 0; i < EM28XX_AUDIO_BUFS; i++) {
65 usb_kill_urb(dev->adev->urb[i]); 65 usb_unlink_urb(dev->adev->urb[i]);
66 usb_free_urb(dev->adev->urb[i]); 66 usb_free_urb(dev->adev->urb[i]);
67 dev->adev->urb[i] = NULL; 67 dev->adev->urb[i] = NULL;
68 } 68 }
@@ -75,7 +75,6 @@ static void em28xx_audio_isocirq(struct urb *urb)
75 struct em28xx *dev = urb->context; 75 struct em28xx *dev = urb->context;
76 int i; 76 int i;
77 unsigned int oldptr; 77 unsigned int oldptr;
78 unsigned long flags;
79 int period_elapsed = 0; 78 int period_elapsed = 0;
80 int status; 79 int status;
81 unsigned char *cp; 80 unsigned char *cp;
@@ -96,9 +95,21 @@ static void em28xx_audio_isocirq(struct urb *urb)
96 if (!length) 95 if (!length)
97 continue; 96 continue;
98 97
99 spin_lock_irqsave(&dev->adev->slock, flags);
100
101 oldptr = dev->adev->hwptr_done_capture; 98 oldptr = dev->adev->hwptr_done_capture;
99 if (oldptr + length >= runtime->buffer_size) {
100 unsigned int cnt =
101 runtime->buffer_size - oldptr;
102 memcpy(runtime->dma_area + oldptr * stride, cp,
103 cnt * stride);
104 memcpy(runtime->dma_area, cp + cnt * stride,
105 length * stride - cnt * stride);
106 } else {
107 memcpy(runtime->dma_area + oldptr * stride, cp,
108 length * stride);
109 }
110
111 snd_pcm_stream_lock(substream);
112
102 dev->adev->hwptr_done_capture += length; 113 dev->adev->hwptr_done_capture += length;
103 if (dev->adev->hwptr_done_capture >= 114 if (dev->adev->hwptr_done_capture >=
104 runtime->buffer_size) 115 runtime->buffer_size)
@@ -113,19 +124,7 @@ static void em28xx_audio_isocirq(struct urb *urb)
113 period_elapsed = 1; 124 period_elapsed = 1;
114 } 125 }
115 126
116 spin_unlock_irqrestore(&dev->adev->slock, flags); 127 snd_pcm_stream_unlock(substream);
117
118 if (oldptr + length >= runtime->buffer_size) {
119 unsigned int cnt =
120 runtime->buffer_size - oldptr;
121 memcpy(runtime->dma_area + oldptr * stride, cp,
122 cnt * stride);
123 memcpy(runtime->dma_area, cp + cnt * stride,
124 length * stride - cnt * stride);
125 } else {
126 memcpy(runtime->dma_area + oldptr * stride, cp,
127 length * stride);
128 }
129 } 128 }
130 if (period_elapsed) 129 if (period_elapsed)
131 snd_pcm_period_elapsed(substream); 130 snd_pcm_period_elapsed(substream);