diff options
Diffstat (limited to 'sound/soc/soc-dmaengine-pcm.c')
-rw-r--r-- | sound/soc/soc-dmaengine-pcm.c | 33 |
1 files changed, 30 insertions, 3 deletions
diff --git a/sound/soc/soc-dmaengine-pcm.c b/sound/soc/soc-dmaengine-pcm.c index 475695234b3d..5df529eda251 100644 --- a/sound/soc/soc-dmaengine-pcm.c +++ b/sound/soc/soc-dmaengine-pcm.c | |||
@@ -30,6 +30,7 @@ | |||
30 | 30 | ||
31 | struct dmaengine_pcm_runtime_data { | 31 | struct dmaengine_pcm_runtime_data { |
32 | struct dma_chan *dma_chan; | 32 | struct dma_chan *dma_chan; |
33 | dma_cookie_t cookie; | ||
33 | 34 | ||
34 | unsigned int pos; | 35 | unsigned int pos; |
35 | 36 | ||
@@ -153,7 +154,7 @@ static int dmaengine_pcm_prepare_and_submit(struct snd_pcm_substream *substream) | |||
153 | 154 | ||
154 | desc->callback = dmaengine_pcm_dma_complete; | 155 | desc->callback = dmaengine_pcm_dma_complete; |
155 | desc->callback_param = substream; | 156 | desc->callback_param = substream; |
156 | dmaengine_submit(desc); | 157 | prtd->cookie = dmaengine_submit(desc); |
157 | 158 | ||
158 | return 0; | 159 | return 0; |
159 | } | 160 | } |
@@ -200,6 +201,20 @@ int snd_dmaengine_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
200 | EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_trigger); | 201 | EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_trigger); |
201 | 202 | ||
202 | /** | 203 | /** |
204 | * snd_dmaengine_pcm_pointer_no_residue - dmaengine based PCM pointer implementation | ||
205 | * @substream: PCM substream | ||
206 | * | ||
207 | * This function is deprecated and should not be used by new drivers, as its | ||
208 | * results may be unreliable. | ||
209 | */ | ||
210 | snd_pcm_uframes_t snd_dmaengine_pcm_pointer_no_residue(struct snd_pcm_substream *substream) | ||
211 | { | ||
212 | struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); | ||
213 | return bytes_to_frames(substream->runtime, prtd->pos); | ||
214 | } | ||
215 | EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_pointer_no_residue); | ||
216 | |||
217 | /** | ||
203 | * snd_dmaengine_pcm_pointer - dmaengine based PCM pointer implementation | 218 | * snd_dmaengine_pcm_pointer - dmaengine based PCM pointer implementation |
204 | * @substream: PCM substream | 219 | * @substream: PCM substream |
205 | * | 220 | * |
@@ -209,7 +224,19 @@ EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_trigger); | |||
209 | snd_pcm_uframes_t snd_dmaengine_pcm_pointer(struct snd_pcm_substream *substream) | 224 | snd_pcm_uframes_t snd_dmaengine_pcm_pointer(struct snd_pcm_substream *substream) |
210 | { | 225 | { |
211 | struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); | 226 | struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); |
212 | return bytes_to_frames(substream->runtime, prtd->pos); | 227 | struct dma_tx_state state; |
228 | enum dma_status status; | ||
229 | unsigned int buf_size; | ||
230 | unsigned int pos = 0; | ||
231 | |||
232 | status = dmaengine_tx_status(prtd->dma_chan, prtd->cookie, &state); | ||
233 | if (status == DMA_IN_PROGRESS || status == DMA_PAUSED) { | ||
234 | buf_size = snd_pcm_lib_buffer_bytes(substream); | ||
235 | if (state.residue > 0 && state.residue <= buf_size) | ||
236 | pos = buf_size - state.residue; | ||
237 | } | ||
238 | |||
239 | return bytes_to_frames(substream->runtime, pos); | ||
213 | } | 240 | } |
214 | EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_pointer); | 241 | EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_pointer); |
215 | 242 | ||
@@ -243,7 +270,7 @@ static int dmaengine_pcm_request_channel(struct dmaengine_pcm_runtime_data *prtd | |||
243 | * Note that this function will use private_data field of the substream's | 270 | * Note that this function will use private_data field of the substream's |
244 | * runtime. So it is not availabe to your pcm driver implementation. If you need | 271 | * runtime. So it is not availabe to your pcm driver implementation. If you need |
245 | * to keep additional data attached to a substream use | 272 | * to keep additional data attached to a substream use |
246 | * snd_dmaeinge_pcm_{set,get}_data. | 273 | * snd_dmaengine_pcm_{set,get}_data. |
247 | */ | 274 | */ |
248 | int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream, | 275 | int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream, |
249 | dma_filter_fn filter_fn, void *filter_data) | 276 | dma_filter_fn filter_fn, void *filter_data) |