[alsa-devel] Question about struct snd_soc_dai() :: cpu_dai->codec

Kuninori Morimoto kuninori.morimoto.gx at renesas.com
Thu Aug 4 04:38:33 CEST 2016


Hi Lars

> I think moving forward we should get rid of the whole CPU/CODEC/platform
> concept. This is an outdated view of how the hardware looks like. When ASoC
> was initially introduce all hardware basically had a CPU side DAI, a CODEC
> side DAI and a DMA. The DMA was connected to the CPU DAI and the CPU DAI was
> connected to the CODEC DAI and that was it. The CPU side was also really
> simple, no signal processing, no signal routing, just the raw audio data
> directly transferred via DMA (or PIO sometimes) to the CPU DAI controller.
> And all digital audio was assumed to be in a single digital domain running
> at them same clock rate.
> 
> This no longer reflects todays typical systems. Sometimes you have more than
> those three components (e.g. additional amplifier IC, BT chip ...),
> sometimes you less (just a DAC or ADC directly connected to a DMA in the
> SoC). You often have complex routing and processing capabilities on the host
> side. Also you have often multiple digital domains with sample-rate
> converters between them.
> 
> Yet still at the core ASoC keeps the CPU/CODEC/platform concept. DPCM e.g.
> tries to work with these concepts by introducing frontend and backend DAIs
> and use dummy components to compensate for when the software model does not
> match the hardware model. This makes it code more complicated than it has to
> be and less efficient than it can be.

I agree to your opinion.
OTOH, we would like to use/keep existing current all drivers.
Thus, I think we need super many small and slow steps.
Or, we need new ASoC2 ?

I can agree that we should get rid of current CPU/Codec/Platform,
but, removing all of them is a little bit over-kill for me.
I think ALSA SoC "framework" should care "component" only,
and it doesn't care what it was.
OTOH "driver" side can use existing CPU/Codec/Platform and/or AUX/compr
etc as helper ? (I'm not sure detail of AUX/compr actually...)
And each "component" has "dai".

My image is like this.
This allows many / few components, and many / few DAIs.
Current DPCM style is automatically supported,
and it is easy to add new style device.
What do you think ?

/*
 * DAI has parent (= component) pointer
 * and rtd interface list_head
 */
struct snd_soc_dai {
	...
	struct snd_soc_component *component; /* parent */
	struct list_head *dai_node; /* struct snd_soc_pcm_runtime */
};

/*
 * Each component has at least 1 DAI
 *
 * CPU/Codec will have many DAIs
 * Card/Platform and other will have dummy DAI as interface
 */
struct snd_soc_component {
	...
	struct snd_soc_dai *dais;
};

/*
 * We can use Card/CPU/Codec/Platform/AUX/COMPR helper,
 * all includes "component".
 * Of course each driver can create original one,
 * or don't use helper is no problem
 */
struct snd_soc_card {
	...
	struct snd_soc_component component;
};

struct snd_soc_cpu {
	...
	struct snd_soc_component component;
};

struct snd_soc_codec {
	...
	struct snd_soc_component component;
};

struct snd_soc_platform {
	...
	struct snd_soc_component component;
};

struct snd_soc_aux {
	...
	struct snd_soc_component component;
};
struct snd_soc_compr {
	...
	struct snd_soc_component component;
};

...

/*
 * rtd has each DAI interface list.
 * But it doesn't care what it was
 */
struct snd_soc_pcm_runtime {
	...
	struct list_head *dai_node_head; /* struct snd_soc_dai */
}

/*
 * each function just call dai or component function
 * it doesn't care what it was
 */
static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_component *component;
	struct snd_soc_dai *dai;
	int ret = 0;

	/*
	 * call each component's ops
	 */
	list_for_each_entry(dai, rtd->xxx) {
		component = snd_soc_dai_to_component(dai);
		ret = component->ops->trigger(dai, xxx);
		if (ret < 0)
			goto trigger_end;
	}

trigger_end:
	return ret;
}


More information about the Alsa-devel mailing list