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; }