So the point is to concentrate only on DMA transfer stuff at first. Once after confirmed it's working, continue to the new DSP features.,
Ok, that makes sense.
A remaining question is:
- what is the condition to operate DSP transfer? Must all PCM streams
be closed and streams are released?
Yes, all PCM streams need to be closed and released for the DSP transfer. Since the driver loads the DSP during the init phase, there shouldn't be any active streams at that time.
- Ian
Notice The information in this message is confidential and may be legally privileged. It is intended solely for the addressee. Access to this message by anyone else is unauthorized. If you are not the intended recipient, any disclosure, copying or distribution of the message, or any action taken by you in reliance on it, is prohibited and may be unlawful. This email is for communication purposes only. It is not intended to constitute an offer or form a binding agreement. Our company accepts no liability for the content of this email, or for the consequences of any actions taken on the basis of the information provided. If you have received this message in error, please delete it and contact the sender immediately. Thank you.
Takashi Iwai tiwai@suse.de To 08/11/2012 12:12 AM Ian Minett ian_minett@creativelabs.com cc alsa-devel@alsa-project.org Subject Re: [PATCHv2.1-CA0132 HDA Codec 2/2] Add DSP loader code to CA0132 codec
At Fri, 10 Aug 2012 23:17:52 -0700, Ian Minett wrote:
From: Ian Minett ian_minett@creativelabs.com
Draft patch to add new DSP loader code, with calls to load_dsp_xxxx() functions.
Signed-off-by: Ian Minett ian_minett@creativelabs.com
(snip)
@@ -2113,9 +1994,7 @@ static int dma_set_state(struct dma_engine *dma, enum dma_state state) return 0; }
azx_pcm_trigger(dma->substream, cmd);
return 0;
return load_dsp_trigger(dma->codec->bus, cmd);
Maybe we just need to pass a boolean to start/stop.
static unsigned int dma_get_buffer_size(struct dma_engine *dma) @@ -2128,15 +2007,6 @@ static unsigned int *dma_get_buffer_addr(struct dma_engine *dma) return dma->m_buffer_addr; }
-static int dma_free_buffer(struct dma_engine *dma) -{
azx_pcm_hw_free(dma->substream);
azx_pcm_close(dma->substream);
kfree(dma->substream->runtime);
dma->substream->runtime = NULL;
return 0;
OK, I forgot that a cleanup callback is also required...
dma_engine->codec = codec;
dma_convert_to_hda_format(format, &hda_format);
dma_engine->m_converter_format = hda_format;
dma_engine->m_buffer_size =
ovly ? DSP_DMA_WRITE_BUFLEN_OVLY : DSP_DMA_WRITE_BUFLEN_INIT;
dma_engine->m_buffer_addr = kzalloc(dma_engine->m_buffer_size,
GFP_KERNEL);
Allocating the DMA transfer buffer via kmalloc doesn't work. The buffer must be aligned and coherent. Thus it's better to let the buffer management in hda_intel.c.
In the end, what we need in hda_intel.c are: - a function to allocate buffer, setup BDL and DMA, return the pointer - a function to start/stop transfer - a function to clean up DMA, release the buffer
Thus the hda_bus_ops will gain the following ops:
/* bus operators */ struct hda_bus_ops { ... #ifdef CONFIG_SND_HDA_LOAD_DSP /* prepare DSP transfer */ void *(*load_dsp_prepare)(struct hda_codec *codec, unsigned int format, unsigned int byte_size); /* start/stop DSP transfer */ void (*load_dsp_trigger)(struct hda_codec *codec, bool start); /* clean up DSP transfer */ void (*load_dsp_cleanup)(struct hda_codec *codec, void *buf, unsigned int byte_size); #endif };
Then define the function like
static inline void * snd_hda_codec_load_dsp_prepare(struct hda_codec *codec, unsigned int format, unsigned int size) { return codec->bus->ops.load_dsp_prepare(codec, format, size); }
and so on.
A remaining question is: - what is the condition to operate DSP transfer? Must all PCM streams be closed and streams are released?
Takashi
ForwardSourceID:NT0001D94A