Lines Matching +full:front +full:- +full:end
1 // SPDX-License-Identifier: GPL-2.0
9 #include <linux/dma-mapping.h>
11 #include <linux/platform_data/dma-imx.h>
37 chan->private = param; in filter()
45 struct snd_pcm_runtime *runtime = substream->runtime; in fsl_asrc_dma_complete()
46 struct fsl_asrc_pair *pair = runtime->private_data; in fsl_asrc_dma_complete()
48 pair->pos += snd_pcm_lib_period_bytes(substream); in fsl_asrc_dma_complete()
49 if (pair->pos >= snd_pcm_lib_buffer_bytes(substream)) in fsl_asrc_dma_complete()
50 pair->pos = 0; in fsl_asrc_dma_complete()
58 u8 dir = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? OUT : IN; in fsl_asrc_dma_prepare_and_submit()
59 struct snd_pcm_runtime *runtime = substream->runtime; in fsl_asrc_dma_prepare_and_submit()
60 struct fsl_asrc_pair *pair = runtime->private_data; in fsl_asrc_dma_prepare_and_submit()
61 struct device *dev = component->dev; in fsl_asrc_dma_prepare_and_submit()
64 /* Prepare and submit Front-End DMA channel */ in fsl_asrc_dma_prepare_and_submit()
65 if (!substream->runtime->no_period_wakeup) in fsl_asrc_dma_prepare_and_submit()
68 pair->pos = 0; in fsl_asrc_dma_prepare_and_submit()
69 pair->desc[!dir] = dmaengine_prep_dma_cyclic( in fsl_asrc_dma_prepare_and_submit()
70 pair->dma_chan[!dir], runtime->dma_addr, in fsl_asrc_dma_prepare_and_submit()
74 if (!pair->desc[!dir]) { in fsl_asrc_dma_prepare_and_submit()
75 dev_err(dev, "failed to prepare slave DMA for Front-End\n"); in fsl_asrc_dma_prepare_and_submit()
76 return -ENOMEM; in fsl_asrc_dma_prepare_and_submit()
79 pair->desc[!dir]->callback = fsl_asrc_dma_complete; in fsl_asrc_dma_prepare_and_submit()
80 pair->desc[!dir]->callback_param = substream; in fsl_asrc_dma_prepare_and_submit()
82 dmaengine_submit(pair->desc[!dir]); in fsl_asrc_dma_prepare_and_submit()
84 /* Prepare and submit Back-End DMA channel */ in fsl_asrc_dma_prepare_and_submit()
85 pair->desc[dir] = dmaengine_prep_dma_cyclic( in fsl_asrc_dma_prepare_and_submit()
86 pair->dma_chan[dir], 0xffff, 64, 64, DMA_DEV_TO_DEV, 0); in fsl_asrc_dma_prepare_and_submit()
87 if (!pair->desc[dir]) { in fsl_asrc_dma_prepare_and_submit()
88 dev_err(dev, "failed to prepare slave DMA for Back-End\n"); in fsl_asrc_dma_prepare_and_submit()
89 return -ENOMEM; in fsl_asrc_dma_prepare_and_submit()
92 dmaengine_submit(pair->desc[dir]); in fsl_asrc_dma_prepare_and_submit()
100 struct snd_pcm_runtime *runtime = substream->runtime; in fsl_asrc_dma_trigger()
101 struct fsl_asrc_pair *pair = runtime->private_data; in fsl_asrc_dma_trigger()
111 dma_async_issue_pending(pair->dma_chan[IN]); in fsl_asrc_dma_trigger()
112 dma_async_issue_pending(pair->dma_chan[OUT]); in fsl_asrc_dma_trigger()
117 dmaengine_terminate_all(pair->dma_chan[OUT]); in fsl_asrc_dma_trigger()
118 dmaengine_terminate_all(pair->dma_chan[IN]); in fsl_asrc_dma_trigger()
121 return -EINVAL; in fsl_asrc_dma_trigger()
133 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; in fsl_asrc_dma_hw_params()
136 struct snd_pcm_runtime *runtime = substream->runtime; in fsl_asrc_dma_hw_params()
137 struct fsl_asrc_pair *pair = runtime->private_data; in fsl_asrc_dma_hw_params()
140 struct fsl_asrc *asrc = pair->asrc; in fsl_asrc_dma_hw_params()
142 enum asrc_pair_index index = pair->index; in fsl_asrc_dma_hw_params()
143 struct device *dev = component->dev; in fsl_asrc_dma_hw_params()
144 int stream = substream->stream; in fsl_asrc_dma_hw_params()
152 /* Fetch the Back-End dma_data from DPCM */ in fsl_asrc_dma_hw_params()
154 struct snd_soc_pcm_runtime *be = dpcm->be; in fsl_asrc_dma_hw_params()
158 if (dpcm->fe != rtd) in fsl_asrc_dma_hw_params()
163 dev_be = dai->dev; in fsl_asrc_dma_hw_params()
168 dev_err(dev, "failed to get the substream of Back-End\n"); in fsl_asrc_dma_hw_params()
169 return -EINVAL; in fsl_asrc_dma_hw_params()
172 /* Override dma_data of the Front-End and config its dmaengine */ in fsl_asrc_dma_hw_params()
174 dma_params_fe->addr = asrc->paddr + asrc->get_fifo_addr(!dir, index); in fsl_asrc_dma_hw_params()
175 dma_params_fe->maxburst = dma_params_be->maxburst; in fsl_asrc_dma_hw_params()
177 pair->dma_chan[!dir] = asrc->get_dma_channel(pair, !dir); in fsl_asrc_dma_hw_params()
178 if (!pair->dma_chan[!dir]) { in fsl_asrc_dma_hw_params()
180 return -EINVAL; in fsl_asrc_dma_hw_params()
186 dev_err(dev, "failed to prepare DMA config for Front-End\n"); in fsl_asrc_dma_hw_params()
190 ret = dmaengine_slave_config(pair->dma_chan[!dir], &config_fe); in fsl_asrc_dma_hw_params()
192 dev_err(dev, "failed to config DMA channel for Front-End\n"); in fsl_asrc_dma_hw_params()
196 /* Request and config DMA channel for Back-End */ in fsl_asrc_dma_hw_params()
202 * The Back-End device might have already requested a DMA channel, in fsl_asrc_dma_hw_params()
207 be_chan = soc_component_to_pcm(component_be)->chan[substream->stream]; in fsl_asrc_dma_hw_params()
217 * Back-End device directly via dma_request_slave_channel. in fsl_asrc_dma_hw_params()
219 if (!asrc->use_edma) { in fsl_asrc_dma_hw_params()
220 /* Get DMA request of Back-End */ in fsl_asrc_dma_hw_params()
221 tmp_data = tmp_chan->private; in fsl_asrc_dma_hw_params()
222 pair->dma_data.dma_request = tmp_data->dma_request; in fsl_asrc_dma_hw_params()
226 /* Get DMA request of Front-End */ in fsl_asrc_dma_hw_params()
227 tmp_chan = asrc->get_dma_channel(pair, dir); in fsl_asrc_dma_hw_params()
228 tmp_data = tmp_chan->private; in fsl_asrc_dma_hw_params()
229 pair->dma_data.dma_request2 = tmp_data->dma_request; in fsl_asrc_dma_hw_params()
230 pair->dma_data.peripheral_type = tmp_data->peripheral_type; in fsl_asrc_dma_hw_params()
231 pair->dma_data.priority = tmp_data->priority; in fsl_asrc_dma_hw_params()
234 pair->dma_chan[dir] = in fsl_asrc_dma_hw_params()
235 dma_request_channel(mask, filter, &pair->dma_data); in fsl_asrc_dma_hw_params()
236 pair->req_dma_chan = true; in fsl_asrc_dma_hw_params()
238 pair->dma_chan[dir] = tmp_chan; in fsl_asrc_dma_hw_params()
239 /* Do not flag to release if we are reusing the Back-End one */ in fsl_asrc_dma_hw_params()
240 pair->req_dma_chan = !be_chan; in fsl_asrc_dma_hw_params()
243 if (!pair->dma_chan[dir]) { in fsl_asrc_dma_hw_params()
244 dev_err(dev, "failed to request DMA channel for Back-End\n"); in fsl_asrc_dma_hw_params()
245 return -EINVAL; in fsl_asrc_dma_hw_params()
248 width = snd_pcm_format_physical_width(asrc->asrc_format); in fsl_asrc_dma_hw_params()
250 return -EINVAL; in fsl_asrc_dma_hw_params()
264 config_be.src_maxburst = dma_params_be->maxburst; in fsl_asrc_dma_hw_params()
266 config_be.dst_maxburst = dma_params_be->maxburst; in fsl_asrc_dma_hw_params()
269 config_be.src_addr = asrc->paddr + asrc->get_fifo_addr(OUT, index); in fsl_asrc_dma_hw_params()
270 config_be.dst_addr = dma_params_be->addr; in fsl_asrc_dma_hw_params()
272 config_be.dst_addr = asrc->paddr + asrc->get_fifo_addr(IN, index); in fsl_asrc_dma_hw_params()
273 config_be.src_addr = dma_params_be->addr; in fsl_asrc_dma_hw_params()
276 ret = dmaengine_slave_config(pair->dma_chan[dir], &config_be); in fsl_asrc_dma_hw_params()
278 dev_err(dev, "failed to config DMA channel for Back-End\n"); in fsl_asrc_dma_hw_params()
279 if (pair->req_dma_chan) in fsl_asrc_dma_hw_params()
280 dma_release_channel(pair->dma_chan[dir]); in fsl_asrc_dma_hw_params()
284 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); in fsl_asrc_dma_hw_params()
292 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; in fsl_asrc_dma_hw_free()
293 struct snd_pcm_runtime *runtime = substream->runtime; in fsl_asrc_dma_hw_free()
294 struct fsl_asrc_pair *pair = runtime->private_data; in fsl_asrc_dma_hw_free()
299 if (pair->dma_chan[!dir]) in fsl_asrc_dma_hw_free()
300 dma_release_channel(pair->dma_chan[!dir]); in fsl_asrc_dma_hw_free()
302 /* release dev_to_dev chan if we aren't reusing the Back-End one */ in fsl_asrc_dma_hw_free()
303 if (pair->dma_chan[dir] && pair->req_dma_chan) in fsl_asrc_dma_hw_free()
304 dma_release_channel(pair->dma_chan[dir]); in fsl_asrc_dma_hw_free()
306 pair->dma_chan[!dir] = NULL; in fsl_asrc_dma_hw_free()
307 pair->dma_chan[dir] = NULL; in fsl_asrc_dma_hw_free()
315 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; in fsl_asrc_dma_startup()
317 struct snd_pcm_runtime *runtime = substream->runtime; in fsl_asrc_dma_startup()
319 struct device *dev = component->dev; in fsl_asrc_dma_startup()
327 ret = snd_pcm_hw_constraint_integer(substream->runtime, in fsl_asrc_dma_startup()
334 pair = kzalloc(sizeof(*pair) + asrc->pair_priv_size, GFP_KERNEL); in fsl_asrc_dma_startup()
336 return -ENOMEM; in fsl_asrc_dma_startup()
338 pair->asrc = asrc; in fsl_asrc_dma_startup()
339 pair->private = (void *)pair + sizeof(struct fsl_asrc_pair); in fsl_asrc_dma_startup()
341 runtime->private_data = pair; in fsl_asrc_dma_startup()
347 ret = asrc->request_pair(1, pair); in fsl_asrc_dma_startup()
354 tmp_chan = asrc->get_dma_channel(pair, dir); in fsl_asrc_dma_startup()
357 ret = -EINVAL; in fsl_asrc_dma_startup()
380 asrc->release_pair(pair); in fsl_asrc_dma_startup()
392 struct snd_pcm_runtime *runtime = substream->runtime; in fsl_asrc_dma_shutdown()
393 struct fsl_asrc_pair *pair = runtime->private_data; in fsl_asrc_dma_shutdown()
399 asrc = pair->asrc; in fsl_asrc_dma_shutdown()
401 if (asrc->pair[pair->index] == pair) in fsl_asrc_dma_shutdown()
402 asrc->pair[pair->index] = NULL; in fsl_asrc_dma_shutdown()
413 struct snd_pcm_runtime *runtime = substream->runtime; in fsl_asrc_dma_pcm_pointer()
414 struct fsl_asrc_pair *pair = runtime->private_data; in fsl_asrc_dma_pcm_pointer()
416 return bytes_to_frames(substream->runtime, pair->pos); in fsl_asrc_dma_pcm_pointer()
422 struct snd_card *card = rtd->card->snd_card; in fsl_asrc_dma_pcm_new()
424 struct snd_pcm *pcm = rtd->pcm; in fsl_asrc_dma_pcm_new()
427 ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32)); in fsl_asrc_dma_pcm_new()
429 dev_err(card->dev, "failed to set DMA mask\n"); in fsl_asrc_dma_pcm_new()
434 substream = pcm->streams[i].substream; in fsl_asrc_dma_pcm_new()
438 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, pcm->card->dev, in fsl_asrc_dma_pcm_new()
439 FSL_ASRC_DMABUF_SIZE, &substream->dma_buffer); in fsl_asrc_dma_pcm_new()
441 dev_err(card->dev, "failed to allocate DMA buffer\n"); in fsl_asrc_dma_pcm_new()
449 if (--i == 0 && pcm->streams[i].substream) in fsl_asrc_dma_pcm_new()
450 snd_dma_free_pages(&pcm->streams[i].substream->dma_buffer); in fsl_asrc_dma_pcm_new()
462 substream = pcm->streams[i].substream; in fsl_asrc_dma_pcm_free()
466 snd_dma_free_pages(&substream->dma_buffer); in fsl_asrc_dma_pcm_free()
467 substream->dma_buffer.area = NULL; in fsl_asrc_dma_pcm_free()
468 substream->dma_buffer.addr = 0; in fsl_asrc_dma_pcm_free()