diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/video/em28xx/em28xx-audio.c | 37 |
1 files changed, 24 insertions, 13 deletions
diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c index ac3292d7646c..dfac2e042a52 100644 --- a/drivers/media/video/em28xx/em28xx-audio.c +++ b/drivers/media/video/em28xx/em28xx-audio.c | |||
@@ -75,7 +75,9 @@ 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 | #ifdef NO_PCM_LOCK | ||
78 | unsigned long flags; | 79 | unsigned long flags; |
80 | #endif | ||
79 | int period_elapsed = 0; | 81 | int period_elapsed = 0; |
80 | int status; | 82 | int status; |
81 | unsigned char *cp; | 83 | unsigned char *cp; |
@@ -96,9 +98,26 @@ static void em28xx_audio_isocirq(struct urb *urb) | |||
96 | if (!length) | 98 | if (!length) |
97 | continue; | 99 | continue; |
98 | 100 | ||
101 | #ifdef NO_PCM_LOCK | ||
99 | spin_lock_irqsave(&dev->adev->slock, flags); | 102 | spin_lock_irqsave(&dev->adev->slock, flags); |
100 | 103 | #endif | |
101 | oldptr = dev->adev->hwptr_done_capture; | 104 | oldptr = dev->adev->hwptr_done_capture; |
105 | if (oldptr + length >= runtime->buffer_size) { | ||
106 | unsigned int cnt = | ||
107 | runtime->buffer_size - oldptr; | ||
108 | memcpy(runtime->dma_area + oldptr * stride, cp, | ||
109 | cnt * stride); | ||
110 | memcpy(runtime->dma_area, cp + cnt * stride, | ||
111 | length * stride - cnt * stride); | ||
112 | } else { | ||
113 | memcpy(runtime->dma_area + oldptr * stride, cp, | ||
114 | length * stride); | ||
115 | } | ||
116 | |||
117 | #ifndef NO_PCM_LOCK | ||
118 | snd_pcm_stream_lock(substream); | ||
119 | #endif | ||
120 | |||
102 | dev->adev->hwptr_done_capture += length; | 121 | dev->adev->hwptr_done_capture += length; |
103 | if (dev->adev->hwptr_done_capture >= | 122 | if (dev->adev->hwptr_done_capture >= |
104 | runtime->buffer_size) | 123 | runtime->buffer_size) |
@@ -113,19 +132,11 @@ static void em28xx_audio_isocirq(struct urb *urb) | |||
113 | period_elapsed = 1; | 132 | period_elapsed = 1; |
114 | } | 133 | } |
115 | 134 | ||
135 | #ifdef NO_PCM_LOCK | ||
116 | spin_unlock_irqrestore(&dev->adev->slock, flags); | 136 | spin_unlock_irqrestore(&dev->adev->slock, flags); |
117 | 137 | #else | |
118 | if (oldptr + length >= runtime->buffer_size) { | 138 | snd_pcm_stream_unlock(substream); |
119 | unsigned int cnt = | 139 | #endif |
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 | } | 140 | } |
130 | if (period_elapsed) | 141 | if (period_elapsed) |
131 | snd_pcm_period_elapsed(substream); | 142 | snd_pcm_period_elapsed(substream); |