Lines Matching +full:0 +full:- +full:based

1 // SPDX-License-Identifier: GPL-2.0-or-later
4 * Author: Lars-Peter Clausen <lars@metafoo.de>
6 * Based on:
7 * imx-pcm-dma-mx2.c, Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
8 * mxs-pcm.c, Copyright (C) 2011 Freescale Semiconductor, Inc.
9 * ep93xx-pcm.c, Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
32 return substream->runtime->private_data;
39 return prtd->dma_chan;
44 * snd_hwparams_to_dma_slave_config - Convert hw_params to dma_slave_config
50 * and hw_params in a dmaengine based PCM driver implementation.
63 return -EINVAL;
75 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
76 slave_config->direction = DMA_MEM_TO_DEV;
77 slave_config->dst_addr_width = buswidth;
79 slave_config->direction = DMA_DEV_TO_MEM;
80 slave_config->src_addr_width = buswidth;
83 slave_config->device_fc = false;
85 return 0;
90 * snd_dmaengine_pcm_set_config_from_dai_data() - Initializes a dma slave config
111 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
112 slave_config->dst_addr = dma_data->addr;
113 slave_config->dst_maxburst = dma_data->maxburst;
114 slave_config->dst_port_window_size = dma_data->port_window_size;
115 if (dma_data->flags & SND_DMAENGINE_PCM_DAI_FLAG_PACK)
116 slave_config->dst_addr_width =
118 if (dma_data->addr_width != DMA_SLAVE_BUSWIDTH_UNDEFINED)
119 slave_config->dst_addr_width = dma_data->addr_width;
121 slave_config->src_addr = dma_data->addr;
122 slave_config->src_maxburst = dma_data->maxburst;
123 slave_config->src_port_window_size = dma_data->port_window_size;
124 if (dma_data->flags & SND_DMAENGINE_PCM_DAI_FLAG_PACK)
125 slave_config->src_addr_width =
127 if (dma_data->addr_width != DMA_SLAVE_BUSWIDTH_UNDEFINED)
128 slave_config->src_addr_width = dma_data->addr_width;
131 slave_config->peripheral_config = dma_data->peripheral_config;
132 slave_config->peripheral_size = dma_data->peripheral_size;
142 new_pos = prtd->pos + snd_pcm_lib_period_bytes(substream);
144 new_pos = 0;
145 prtd->pos = new_pos;
153 struct dma_chan *chan = prtd->dma_chan;
160 if (!substream->runtime->no_period_wakeup)
163 prtd->pos = 0;
165 substream->runtime->dma_addr,
170 return -ENOMEM;
172 desc->callback = dmaengine_pcm_dma_complete;
173 desc->callback_param = substream;
174 prtd->cookie = dmaengine_submit(desc);
176 return 0;
180 * snd_dmaengine_pcm_trigger - dmaengine based PCM trigger implementation
184 * This function can be used as the PCM trigger callback for dmaengine based PCM
187 * Return: 0 on success, a negative error code otherwise
192 struct snd_pcm_runtime *runtime = substream->runtime;
200 dma_async_issue_pending(prtd->dma_chan);
204 dmaengine_resume(prtd->dma_chan);
207 if (runtime->info & SNDRV_PCM_INFO_PAUSE)
208 dmaengine_pause(prtd->dma_chan);
210 dmaengine_terminate_async(prtd->dma_chan);
213 dmaengine_pause(prtd->dma_chan);
216 dmaengine_terminate_async(prtd->dma_chan);
219 return -EINVAL;
222 return 0;
227 * snd_dmaengine_pcm_pointer_no_residue - dmaengine based PCM pointer implementation
238 return bytes_to_frames(substream->runtime, prtd->pos);
243 * snd_dmaengine_pcm_pointer - dmaengine based PCM pointer implementation
246 * This function can be used as the PCM pointer callback for dmaengine based PCM
254 struct snd_pcm_runtime *runtime = substream->runtime;
258 unsigned int pos = 0;
260 status = dmaengine_tx_status(prtd->dma_chan, prtd->cookie, &state);
263 if (state.residue > 0 && state.residue <= buf_size)
264 pos = buf_size - state.residue;
266 runtime->delay = bytes_to_frames(runtime,
275 * snd_dmaengine_pcm_request_channel - Request channel for the dmaengine PCM
297 * snd_dmaengine_pcm_open - Open a dmaengine based PCM substream
305 * Return: 0 on success, a negative error code otherwise
314 return -ENXIO;
316 ret = snd_pcm_hw_constraint_integer(substream->runtime,
318 if (ret < 0)
323 return -ENOMEM;
325 prtd->dma_chan = chan;
327 substream->runtime->private_data = prtd;
329 return 0;
339 status = dmaengine_tx_status(prtd->dma_chan, prtd->cookie, &state);
341 dmaengine_synchronize(prtd->dma_chan);
343 return 0;
354 status = dmaengine_tx_status(prtd->dma_chan, prtd->cookie, &state);
356 dmaengine_terminate_async(prtd->dma_chan);
358 dmaengine_synchronize(prtd->dma_chan);
360 dma_release_channel(prtd->dma_chan);
365 * snd_dmaengine_pcm_close - Close a dmaengine based PCM substream
368 * Return: 0 on success, a negative error code otherwise
373 return 0;
378 * snd_dmaengine_pcm_close_release_chan - Close a dmaengine based PCM
389 return 0;
394 * snd_dmaengine_pcm_refine_runtime_hwparams - Refine runtime hw params
403 * Return: 0 on success, a negative error code otherwise
416 int ret = 0;
419 return -EINVAL;
422 if (ret == 0) {
424 hw->info |= SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME;
426 hw->info |= SNDRV_PCM_INFO_BATCH;
428 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
436 * hw.formats set to 0, meaning no restrictions are in place.
440 if (!(dma_data->flags & SND_DMAENGINE_PCM_DAI_FLAG_PACK))
464 hw->formats |= pcm_format_to_bits(i);