[alsa-devel] [PATCHv2.1-CA0132 HDA Codec 2/2] Add DSP loader code to CA0132 codec
Takashi Iwai
tiwai at suse.de
Sat Aug 11 09:12:44 CEST 2012
At Fri, 10 Aug 2012 23:17:52 -0700,
Ian Minett wrote:
>
> From: Ian Minett <ian_minett at creativelabs.com>
>
> Draft patch to add new DSP loader code, with calls to load_dsp_xxxx() functions.
>
>
> Signed-off-by: Ian Minett <ian_minett at 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
More information about the Alsa-devel
mailing list