[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