As the dma device may support dma-coherent property on the i.MX952,
allocate memory from dma device to make asrc driver to be compatible with
such a case.

Signed-off-by: Shengjiu Wang <[email protected]>
---
 sound/soc/fsl/fsl_asrc_dma.c | 48 ++++++++++++++++++++++++++++++------
 1 file changed, 41 insertions(+), 7 deletions(-)

diff --git a/sound/soc/fsl/fsl_asrc_dma.c b/sound/soc/fsl/fsl_asrc_dma.c
index 7dacc06b2f02..b8fe242d53db 100644
--- a/sound/soc/fsl/fsl_asrc_dma.c
+++ b/sound/soc/fsl/fsl_asrc_dma.c
@@ -449,18 +449,52 @@ fsl_asrc_dma_pcm_pointer(struct snd_soc_component 
*component,
 static int fsl_asrc_dma_pcm_new(struct snd_soc_component *component,
                                struct snd_soc_pcm_runtime *rtd)
 {
-       struct snd_card *card = rtd->card->snd_card;
+       struct device *dev = component->dev;
+       struct fsl_asrc *asrc = dev_get_drvdata(dev);
+       struct fsl_asrc_pair *pair;
        struct snd_pcm *pcm = rtd->pcm;
+       struct dma_chan *chan;
        int ret;
 
-       ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32));
-       if (ret) {
-               dev_err(card->dev, "failed to set DMA mask\n");
-               return ret;
+       pair = kzalloc(sizeof(*pair) + asrc->pair_priv_size, GFP_KERNEL);
+       if (!pair)
+               return -ENOMEM;
+
+       pair->asrc = asrc;
+       pair->private = (void *)pair + sizeof(struct fsl_asrc_pair);
+
+       /* Request a dummy pair, which will be released later.
+        * Request pair function needs channel num as input, for this
+        * dummy pair, we just request "1" channel temporarily.
+        */
+       ret = asrc->request_pair(1, pair);
+       if (ret < 0) {
+               dev_err(dev, "failed to request asrc pair\n");
+               goto req_pair_err;
        }
 
-       return snd_pcm_set_fixed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,
-                                           card->dev, FSL_ASRC_DMABUF_SIZE);
+       /* Request a dummy dma channel, which will be released later. */
+       chan = asrc->get_dma_channel(pair, IN);
+       if (!chan) {
+               dev_err(dev, "failed to get dma channel\n");
+               ret = -EINVAL;
+               goto dma_chan_err;
+       }
+
+       ret = snd_pcm_set_fixed_buffer_all(pcm,
+                                          SNDRV_DMA_TYPE_DEV,
+                                          chan->device->dev,
+                                          FSL_ASRC_DMABUF_SIZE);
+
+       dma_release_channel(chan);
+
+dma_chan_err:
+       asrc->release_pair(pair);
+
+req_pair_err:
+       kfree(pair);
+
+       return ret;
 }
 
 struct snd_soc_component_driver fsl_asrc_component = {
-- 
2.34.1


Reply via email to