aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-dmaengine-pcm.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/soc-dmaengine-pcm.c')
-rw-r--r--sound/soc/soc-dmaengine-pcm.c33
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
31struct dmaengine_pcm_runtime_data { 31struct 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)
200EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_trigger); 201EXPORT_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 */
210snd_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}
215EXPORT_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);
209snd_pcm_uframes_t snd_dmaengine_pcm_pointer(struct snd_pcm_substream *substream) 224snd_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}
214EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_pointer); 241EXPORT_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 */
248int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream, 275int 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)