From 9bebdbf384fa06d118fca171692c9cdbdd5ea1ad Mon Sep 17 00:00:00 2001 From: Rander Wang Date: Tue, 27 Nov 2018 13:22:14 +0800 Subject: [PATCH] link dma: allocate link dma channel at dai_config Fix capture issue with hda codecs. Now the data captured by hda codecs is full of zero. It is caused by mismatch of link dma channel between host and FW. Now host allocates link dma channel at dai config loading stage, and sends it to FW to allocate link dma channel at dai_config function Signed-off-by: Rander Wang --- src/audio/dai.c | 29 +++++++++++++++-------------- src/include/uapi/ipc/dai-intel.h | 3 +-- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/audio/dai.c b/src/audio/dai.c index c5c1b3277206..b8a3393a5a66 100644 --- a/src/audio/dai.c +++ b/src/audio/dai.c @@ -388,18 +388,6 @@ static int dai_params(struct comp_dev *dev) return -EINVAL; } - /* get DMA channel, once the stream_tag is known */ - dd->chan = dma_channel_get(dd->dma, dev->params.stream_tag); - if (dd->chan < 0) { - trace_dai_error("dai_params() error: dma_channel_get() failed"); - return -EINVAL; - } - - /* set up callback */ - dma_set_cb(dd->dma, dd->chan, DMA_IRQ_TYPE_BLOCK | - DMA_IRQ_TYPE_LLIST, dai_dma_cb, dev); - dev->is_dma_connected = 1; - /* for DAI, we should configure its frame_fmt from topology */ dev->params.frame_fmt = dconfig->frame_fmt; @@ -490,8 +478,6 @@ static int dai_reset(struct comp_dev *dev) trace_dai("dai_reset()"); - dma_channel_put(dd->dma, dd->chan); - dma_sg_free(&config->elem_array); dd->dai_pos_blks = 0; @@ -663,6 +649,7 @@ static int dai_position(struct comp_dev *dev, struct sof_ipc_stream_posn *posn) static int dai_config(struct comp_dev *dev, struct sof_ipc_dai_config *config) { struct dai_data *dd = comp_get_drvdata(dev); + int channel = 0; switch (config->type) { case SOF_DAI_INTEL_SSP: @@ -726,6 +713,7 @@ static int dai_config(struct comp_dev *dev, struct sof_ipc_dai_config *config) * this is temp until dai/hda model is changed. */ dev->frame_bytes = 4; + channel = config->hda.link_dma_ch; break; default: /* other types of DAIs not handled for now */ @@ -740,6 +728,19 @@ static int dai_config(struct comp_dev *dev, struct sof_ipc_dai_config *config) return -EINVAL; } + /* channel is ignored by GP dma get function */ + dd->chan = dma_channel_get(dd->dma, channel); + if (dd->chan < 0) { + trace_dai_error("dai_config() error: dma_channel_get() failed"); + return -EIO; + } + + /* set up callback */ + dma_set_cb(dd->dma, dd->chan, DMA_IRQ_TYPE_BLOCK | + DMA_IRQ_TYPE_LLIST, dai_dma_cb, dev); + + dev->is_dma_connected = 1; + return 0; } diff --git a/src/include/uapi/ipc/dai-intel.h b/src/include/uapi/ipc/dai-intel.h index c0ffaffcbe0e..2d459778f631 100644 --- a/src/include/uapi/ipc/dai-intel.h +++ b/src/include/uapi/ipc/dai-intel.h @@ -106,8 +106,7 @@ struct sof_ipc_dai_ssp_params { /* HDA Configuration Request - SOF_IPC_DAI_HDA_CONFIG */ struct sof_ipc_dai_hda_params { - struct sof_ipc_hdr hdr; - /* TODO */ + uint32_t link_dma_ch; } __attribute__((packed)); /* DMIC Configuration Request - SOF_IPC_DAI_DMIC_CONFIG */