18c2ecf20Sopenharmony_ci===========
28c2ecf20Sopenharmony_ciDynamic PCM
38c2ecf20Sopenharmony_ci===========
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ciDescription
68c2ecf20Sopenharmony_ci===========
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ciDynamic PCM allows an ALSA PCM device to digitally route its PCM audio to
98c2ecf20Sopenharmony_civarious digital endpoints during the PCM stream runtime. e.g. PCM0 can route
108c2ecf20Sopenharmony_cidigital audio to I2S DAI0, I2S DAI1 or PDM DAI2. This is useful for on SoC DSP
118c2ecf20Sopenharmony_cidrivers that expose several ALSA PCMs and can route to multiple DAIs.
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ciThe DPCM runtime routing is determined by the ALSA mixer settings in the same
148c2ecf20Sopenharmony_ciway as the analog signal is routed in an ASoC codec driver. DPCM uses a DAPM
158c2ecf20Sopenharmony_cigraph representing the DSP internal audio paths and uses the mixer settings to
168c2ecf20Sopenharmony_cidetermine the path used by each ALSA PCM.
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ciDPCM re-uses all the existing component codec, platform and DAI drivers without
198c2ecf20Sopenharmony_ciany modifications.
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_ciPhone Audio System with SoC based DSP
238c2ecf20Sopenharmony_ci-------------------------------------
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ciConsider the following phone audio subsystem. This will be used in this
268c2ecf20Sopenharmony_cidocument for all examples :-
278c2ecf20Sopenharmony_ci::
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci  | Front End PCMs    |  SoC DSP  | Back End DAIs | Audio devices |
308c2ecf20Sopenharmony_ci  
318c2ecf20Sopenharmony_ci                      *************
328c2ecf20Sopenharmony_ci  PCM0 <------------> *           * <----DAI0-----> Codec Headset
338c2ecf20Sopenharmony_ci                      *           *
348c2ecf20Sopenharmony_ci  PCM1 <------------> *           * <----DAI1-----> Codec Speakers
358c2ecf20Sopenharmony_ci                      *   DSP     *
368c2ecf20Sopenharmony_ci  PCM2 <------------> *           * <----DAI2-----> MODEM
378c2ecf20Sopenharmony_ci                      *           *
388c2ecf20Sopenharmony_ci  PCM3 <------------> *           * <----DAI3-----> BT
398c2ecf20Sopenharmony_ci                      *           *
408c2ecf20Sopenharmony_ci                      *           * <----DAI4-----> DMIC
418c2ecf20Sopenharmony_ci                      *           *
428c2ecf20Sopenharmony_ci                      *           * <----DAI5-----> FM
438c2ecf20Sopenharmony_ci                      *************
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ciThis diagram shows a simple smart phone audio subsystem. It supports Bluetooth,
468c2ecf20Sopenharmony_ciFM digital radio, Speakers, Headset Jack, digital microphones and cellular
478c2ecf20Sopenharmony_cimodem. This sound card exposes 4 DSP front end (FE) ALSA PCM devices and
488c2ecf20Sopenharmony_cisupports 6 back end (BE) DAIs. Each FE PCM can digitally route audio data to any
498c2ecf20Sopenharmony_ciof the BE DAIs. The FE PCM devices can also route audio to more than 1 BE DAI.
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ciExample - DPCM Switching playback from DAI0 to DAI1
548c2ecf20Sopenharmony_ci---------------------------------------------------
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ciAudio is being played to the Headset. After a while the user removes the headset
578c2ecf20Sopenharmony_ciand audio continues playing on the speakers.
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ciPlayback on PCM0 to Headset would look like :-
608c2ecf20Sopenharmony_ci::
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci                      *************
638c2ecf20Sopenharmony_ci  PCM0 <============> *           * <====DAI0=====> Codec Headset
648c2ecf20Sopenharmony_ci                      *           *
658c2ecf20Sopenharmony_ci  PCM1 <------------> *           * <----DAI1-----> Codec Speakers
668c2ecf20Sopenharmony_ci                      *   DSP     *
678c2ecf20Sopenharmony_ci  PCM2 <------------> *           * <----DAI2-----> MODEM
688c2ecf20Sopenharmony_ci                      *           *
698c2ecf20Sopenharmony_ci  PCM3 <------------> *           * <----DAI3-----> BT
708c2ecf20Sopenharmony_ci                      *           *
718c2ecf20Sopenharmony_ci                      *           * <----DAI4-----> DMIC
728c2ecf20Sopenharmony_ci                      *           *
738c2ecf20Sopenharmony_ci                      *           * <----DAI5-----> FM
748c2ecf20Sopenharmony_ci                      *************
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ciThe headset is removed from the jack by user so the speakers must now be used :-
778c2ecf20Sopenharmony_ci::
788c2ecf20Sopenharmony_ci
798c2ecf20Sopenharmony_ci                      *************
808c2ecf20Sopenharmony_ci  PCM0 <============> *           * <----DAI0-----> Codec Headset
818c2ecf20Sopenharmony_ci                      *           *
828c2ecf20Sopenharmony_ci  PCM1 <------------> *           * <====DAI1=====> Codec Speakers
838c2ecf20Sopenharmony_ci                      *   DSP     *
848c2ecf20Sopenharmony_ci  PCM2 <------------> *           * <----DAI2-----> MODEM
858c2ecf20Sopenharmony_ci                      *           *
868c2ecf20Sopenharmony_ci  PCM3 <------------> *           * <----DAI3-----> BT
878c2ecf20Sopenharmony_ci                      *           *
888c2ecf20Sopenharmony_ci                      *           * <----DAI4-----> DMIC
898c2ecf20Sopenharmony_ci                      *           *
908c2ecf20Sopenharmony_ci                      *           * <----DAI5-----> FM
918c2ecf20Sopenharmony_ci                      *************
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_ciThe audio driver processes this as follows :-
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_ci1. Machine driver receives Jack removal event.
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_ci2. Machine driver OR audio HAL disables the Headset path.
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ci3. DPCM runs the PCM trigger(stop), hw_free(), shutdown() operations on DAI0
1008c2ecf20Sopenharmony_ci   for headset since the path is now disabled.
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ci4. Machine driver or audio HAL enables the speaker path.
1038c2ecf20Sopenharmony_ci
1048c2ecf20Sopenharmony_ci5. DPCM runs the PCM ops for startup(), hw_params(), prepare() and
1058c2ecf20Sopenharmony_ci   trigger(start) for DAI1 Speakers since the path is enabled.
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_ciIn this example, the machine driver or userspace audio HAL can alter the routing
1088c2ecf20Sopenharmony_ciand then DPCM will take care of managing the DAI PCM operations to either bring
1098c2ecf20Sopenharmony_cithe link up or down. Audio playback does not stop during this transition.
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_ci
1128c2ecf20Sopenharmony_ci
1138c2ecf20Sopenharmony_ciDPCM machine driver
1148c2ecf20Sopenharmony_ci===================
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_ciThe DPCM enabled ASoC machine driver is similar to normal machine drivers
1178c2ecf20Sopenharmony_ciexcept that we also have to :-
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci1. Define the FE and BE DAI links.
1208c2ecf20Sopenharmony_ci
1218c2ecf20Sopenharmony_ci2. Define any FE/BE PCM operations.
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_ci3. Define widget graph connections.
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_ciFE and BE DAI links
1278c2ecf20Sopenharmony_ci-------------------
1288c2ecf20Sopenharmony_ci::
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_ci  | Front End PCMs    |  SoC DSP  | Back End DAIs | Audio devices |
1318c2ecf20Sopenharmony_ci  
1328c2ecf20Sopenharmony_ci                      *************
1338c2ecf20Sopenharmony_ci  PCM0 <------------> *           * <----DAI0-----> Codec Headset
1348c2ecf20Sopenharmony_ci                      *           *
1358c2ecf20Sopenharmony_ci  PCM1 <------------> *           * <----DAI1-----> Codec Speakers
1368c2ecf20Sopenharmony_ci                      *   DSP     *
1378c2ecf20Sopenharmony_ci  PCM2 <------------> *           * <----DAI2-----> MODEM
1388c2ecf20Sopenharmony_ci                      *           *
1398c2ecf20Sopenharmony_ci  PCM3 <------------> *           * <----DAI3-----> BT
1408c2ecf20Sopenharmony_ci                      *           *
1418c2ecf20Sopenharmony_ci                      *           * <----DAI4-----> DMIC
1428c2ecf20Sopenharmony_ci                      *           *
1438c2ecf20Sopenharmony_ci                      *           * <----DAI5-----> FM
1448c2ecf20Sopenharmony_ci                      *************
1458c2ecf20Sopenharmony_ci
1468c2ecf20Sopenharmony_ciFor the example above we have to define 4 FE DAI links and 6 BE DAI links. The
1478c2ecf20Sopenharmony_ciFE DAI links are defined as follows :-
1488c2ecf20Sopenharmony_ci::
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_ci  static struct snd_soc_dai_link machine_dais[] = {
1518c2ecf20Sopenharmony_ci	{
1528c2ecf20Sopenharmony_ci		.name = "PCM0 System",
1538c2ecf20Sopenharmony_ci		.stream_name = "System Playback",
1548c2ecf20Sopenharmony_ci		.cpu_dai_name = "System Pin",
1558c2ecf20Sopenharmony_ci		.platform_name = "dsp-audio",
1568c2ecf20Sopenharmony_ci		.codec_name = "snd-soc-dummy",
1578c2ecf20Sopenharmony_ci		.codec_dai_name = "snd-soc-dummy-dai",
1588c2ecf20Sopenharmony_ci		.dynamic = 1,
1598c2ecf20Sopenharmony_ci		.trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
1608c2ecf20Sopenharmony_ci		.dpcm_playback = 1,
1618c2ecf20Sopenharmony_ci	},
1628c2ecf20Sopenharmony_ci	.....< other FE and BE DAI links here >
1638c2ecf20Sopenharmony_ci  };
1648c2ecf20Sopenharmony_ci
1658c2ecf20Sopenharmony_ciThis FE DAI link is pretty similar to a regular DAI link except that we also
1668c2ecf20Sopenharmony_ciset the DAI link to a DPCM FE with the ``dynamic = 1``. The supported FE stream
1678c2ecf20Sopenharmony_cidirections should also be set with the ``dpcm_playback`` and ``dpcm_capture``
1688c2ecf20Sopenharmony_ciflags. There is also an option to specify the ordering of the trigger call for
1698c2ecf20Sopenharmony_cieach FE. This allows the ASoC core to trigger the DSP before or after the other
1708c2ecf20Sopenharmony_cicomponents (as some DSPs have strong requirements for the ordering DAI/DSP
1718c2ecf20Sopenharmony_cistart and stop sequences).
1728c2ecf20Sopenharmony_ci
1738c2ecf20Sopenharmony_ciThe FE DAI above sets the codec and code DAIs to dummy devices since the BE is
1748c2ecf20Sopenharmony_cidynamic and will change depending on runtime config.
1758c2ecf20Sopenharmony_ci
1768c2ecf20Sopenharmony_ciThe BE DAIs are configured as follows :-
1778c2ecf20Sopenharmony_ci::
1788c2ecf20Sopenharmony_ci
1798c2ecf20Sopenharmony_ci  static struct snd_soc_dai_link machine_dais[] = {
1808c2ecf20Sopenharmony_ci	.....< FE DAI links here >
1818c2ecf20Sopenharmony_ci	{
1828c2ecf20Sopenharmony_ci		.name = "Codec Headset",
1838c2ecf20Sopenharmony_ci		.cpu_dai_name = "ssp-dai.0",
1848c2ecf20Sopenharmony_ci		.platform_name = "snd-soc-dummy",
1858c2ecf20Sopenharmony_ci		.no_pcm = 1,
1868c2ecf20Sopenharmony_ci		.codec_name = "rt5640.0-001c",
1878c2ecf20Sopenharmony_ci		.codec_dai_name = "rt5640-aif1",
1888c2ecf20Sopenharmony_ci		.ignore_suspend = 1,
1898c2ecf20Sopenharmony_ci		.ignore_pmdown_time = 1,
1908c2ecf20Sopenharmony_ci		.be_hw_params_fixup = hswult_ssp0_fixup,
1918c2ecf20Sopenharmony_ci		.ops = &haswell_ops,
1928c2ecf20Sopenharmony_ci		.dpcm_playback = 1,
1938c2ecf20Sopenharmony_ci		.dpcm_capture = 1,
1948c2ecf20Sopenharmony_ci	},
1958c2ecf20Sopenharmony_ci	.....< other BE DAI links here >
1968c2ecf20Sopenharmony_ci  };
1978c2ecf20Sopenharmony_ci
1988c2ecf20Sopenharmony_ciThis BE DAI link connects DAI0 to the codec (in this case RT5460 AIF1). It sets
1998c2ecf20Sopenharmony_cithe ``no_pcm`` flag to mark it has a BE and sets flags for supported stream
2008c2ecf20Sopenharmony_cidirections using ``dpcm_playback`` and ``dpcm_capture`` above.
2018c2ecf20Sopenharmony_ci
2028c2ecf20Sopenharmony_ciThe BE has also flags set for ignoring suspend and PM down time. This allows
2038c2ecf20Sopenharmony_cithe BE to work in a hostless mode where the host CPU is not transferring data
2048c2ecf20Sopenharmony_cilike a BT phone call :-
2058c2ecf20Sopenharmony_ci::
2068c2ecf20Sopenharmony_ci
2078c2ecf20Sopenharmony_ci                      *************
2088c2ecf20Sopenharmony_ci  PCM0 <------------> *           * <----DAI0-----> Codec Headset
2098c2ecf20Sopenharmony_ci                      *           *
2108c2ecf20Sopenharmony_ci  PCM1 <------------> *           * <----DAI1-----> Codec Speakers
2118c2ecf20Sopenharmony_ci                      *   DSP     *
2128c2ecf20Sopenharmony_ci  PCM2 <------------> *           * <====DAI2=====> MODEM
2138c2ecf20Sopenharmony_ci                      *           *
2148c2ecf20Sopenharmony_ci  PCM3 <------------> *           * <====DAI3=====> BT
2158c2ecf20Sopenharmony_ci                      *           *
2168c2ecf20Sopenharmony_ci                      *           * <----DAI4-----> DMIC
2178c2ecf20Sopenharmony_ci                      *           *
2188c2ecf20Sopenharmony_ci                      *           * <----DAI5-----> FM
2198c2ecf20Sopenharmony_ci                      *************
2208c2ecf20Sopenharmony_ci
2218c2ecf20Sopenharmony_ciThis allows the host CPU to sleep while the DSP, MODEM DAI and the BT DAI are
2228c2ecf20Sopenharmony_cistill in operation.
2238c2ecf20Sopenharmony_ci
2248c2ecf20Sopenharmony_ciA BE DAI link can also set the codec to a dummy device if the codec is a device
2258c2ecf20Sopenharmony_cithat is managed externally.
2268c2ecf20Sopenharmony_ci
2278c2ecf20Sopenharmony_ciLikewise a BE DAI can also set a dummy cpu DAI if the CPU DAI is managed by the
2288c2ecf20Sopenharmony_ciDSP firmware.
2298c2ecf20Sopenharmony_ci
2308c2ecf20Sopenharmony_ci
2318c2ecf20Sopenharmony_ciFE/BE PCM operations
2328c2ecf20Sopenharmony_ci--------------------
2338c2ecf20Sopenharmony_ci
2348c2ecf20Sopenharmony_ciThe BE above also exports some PCM operations and a ``fixup`` callback. The fixup
2358c2ecf20Sopenharmony_cicallback is used by the machine driver to (re)configure the DAI based upon the
2368c2ecf20Sopenharmony_ciFE hw params. i.e. the DSP may perform SRC or ASRC from the FE to BE.
2378c2ecf20Sopenharmony_ci
2388c2ecf20Sopenharmony_cie.g. DSP converts all FE hw params to run at fixed rate of 48k, 16bit, stereo for
2398c2ecf20Sopenharmony_ciDAI0. This means all FE hw_params have to be fixed in the machine driver for
2408c2ecf20Sopenharmony_ciDAI0 so that the DAI is running at desired configuration regardless of the FE
2418c2ecf20Sopenharmony_ciconfiguration.
2428c2ecf20Sopenharmony_ci::
2438c2ecf20Sopenharmony_ci
2448c2ecf20Sopenharmony_ci  static int dai0_fixup(struct snd_soc_pcm_runtime *rtd,
2458c2ecf20Sopenharmony_ci			struct snd_pcm_hw_params *params)
2468c2ecf20Sopenharmony_ci  {
2478c2ecf20Sopenharmony_ci	struct snd_interval *rate = hw_param_interval(params,
2488c2ecf20Sopenharmony_ci			SNDRV_PCM_HW_PARAM_RATE);
2498c2ecf20Sopenharmony_ci	struct snd_interval *channels = hw_param_interval(params,
2508c2ecf20Sopenharmony_ci						SNDRV_PCM_HW_PARAM_CHANNELS);
2518c2ecf20Sopenharmony_ci
2528c2ecf20Sopenharmony_ci	/* The DSP will convert the FE rate to 48k, stereo */
2538c2ecf20Sopenharmony_ci	rate->min = rate->max = 48000;
2548c2ecf20Sopenharmony_ci	channels->min = channels->max = 2;
2558c2ecf20Sopenharmony_ci
2568c2ecf20Sopenharmony_ci	/* set DAI0 to 16 bit */
2578c2ecf20Sopenharmony_ci	params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);
2588c2ecf20Sopenharmony_ci	return 0;
2598c2ecf20Sopenharmony_ci  }
2608c2ecf20Sopenharmony_ci
2618c2ecf20Sopenharmony_ciThe other PCM operation are the same as for regular DAI links. Use as necessary.
2628c2ecf20Sopenharmony_ci
2638c2ecf20Sopenharmony_ci
2648c2ecf20Sopenharmony_ciWidget graph connections
2658c2ecf20Sopenharmony_ci------------------------
2668c2ecf20Sopenharmony_ci
2678c2ecf20Sopenharmony_ciThe BE DAI links will normally be connected to the graph at initialisation time
2688c2ecf20Sopenharmony_ciby the ASoC DAPM core. However, if the BE codec or BE DAI is a dummy then this
2698c2ecf20Sopenharmony_cihas to be set explicitly in the driver :-
2708c2ecf20Sopenharmony_ci::
2718c2ecf20Sopenharmony_ci
2728c2ecf20Sopenharmony_ci  /* BE for codec Headset -  DAI0 is dummy and managed by DSP FW */
2738c2ecf20Sopenharmony_ci  {"DAI0 CODEC IN", NULL, "AIF1 Capture"},
2748c2ecf20Sopenharmony_ci  {"AIF1 Playback", NULL, "DAI0 CODEC OUT"},
2758c2ecf20Sopenharmony_ci
2768c2ecf20Sopenharmony_ci
2778c2ecf20Sopenharmony_ciWriting a DPCM DSP driver
2788c2ecf20Sopenharmony_ci=========================
2798c2ecf20Sopenharmony_ci
2808c2ecf20Sopenharmony_ciThe DPCM DSP driver looks much like a standard platform class ASoC driver
2818c2ecf20Sopenharmony_cicombined with elements from a codec class driver. A DSP platform driver must
2828c2ecf20Sopenharmony_ciimplement :-
2838c2ecf20Sopenharmony_ci
2848c2ecf20Sopenharmony_ci1. Front End PCM DAIs - i.e. struct snd_soc_dai_driver.
2858c2ecf20Sopenharmony_ci
2868c2ecf20Sopenharmony_ci2. DAPM graph showing DSP audio routing from FE DAIs to BEs.
2878c2ecf20Sopenharmony_ci
2888c2ecf20Sopenharmony_ci3. DAPM widgets from DSP graph.
2898c2ecf20Sopenharmony_ci
2908c2ecf20Sopenharmony_ci4. Mixers for gains, routing, etc.
2918c2ecf20Sopenharmony_ci
2928c2ecf20Sopenharmony_ci5. DMA configuration.
2938c2ecf20Sopenharmony_ci
2948c2ecf20Sopenharmony_ci6. BE AIF widgets.
2958c2ecf20Sopenharmony_ci
2968c2ecf20Sopenharmony_ciItems 6 is important for routing the audio outside of the DSP. AIF need to be
2978c2ecf20Sopenharmony_cidefined for each BE and each stream direction. e.g for BE DAI0 above we would
2988c2ecf20Sopenharmony_cihave :-
2998c2ecf20Sopenharmony_ci::
3008c2ecf20Sopenharmony_ci
3018c2ecf20Sopenharmony_ci  SND_SOC_DAPM_AIF_IN("DAI0 RX", NULL, 0, SND_SOC_NOPM, 0, 0),
3028c2ecf20Sopenharmony_ci  SND_SOC_DAPM_AIF_OUT("DAI0 TX", NULL, 0, SND_SOC_NOPM, 0, 0),
3038c2ecf20Sopenharmony_ci
3048c2ecf20Sopenharmony_ciThe BE AIF are used to connect the DSP graph to the graphs for the other
3058c2ecf20Sopenharmony_cicomponent drivers (e.g. codec graph).
3068c2ecf20Sopenharmony_ci
3078c2ecf20Sopenharmony_ci
3088c2ecf20Sopenharmony_ciHostless PCM streams
3098c2ecf20Sopenharmony_ci====================
3108c2ecf20Sopenharmony_ci
3118c2ecf20Sopenharmony_ciA hostless PCM stream is a stream that is not routed through the host CPU. An
3128c2ecf20Sopenharmony_ciexample of this would be a phone call from handset to modem.
3138c2ecf20Sopenharmony_ci::
3148c2ecf20Sopenharmony_ci
3158c2ecf20Sopenharmony_ci                      *************
3168c2ecf20Sopenharmony_ci  PCM0 <------------> *           * <----DAI0-----> Codec Headset
3178c2ecf20Sopenharmony_ci                      *           *
3188c2ecf20Sopenharmony_ci  PCM1 <------------> *           * <====DAI1=====> Codec Speakers/Mic
3198c2ecf20Sopenharmony_ci                      *   DSP     *
3208c2ecf20Sopenharmony_ci  PCM2 <------------> *           * <====DAI2=====> MODEM
3218c2ecf20Sopenharmony_ci                      *           *
3228c2ecf20Sopenharmony_ci  PCM3 <------------> *           * <----DAI3-----> BT
3238c2ecf20Sopenharmony_ci                      *           *
3248c2ecf20Sopenharmony_ci                      *           * <----DAI4-----> DMIC
3258c2ecf20Sopenharmony_ci                      *           *
3268c2ecf20Sopenharmony_ci                      *           * <----DAI5-----> FM
3278c2ecf20Sopenharmony_ci                      *************
3288c2ecf20Sopenharmony_ci
3298c2ecf20Sopenharmony_ciIn this case the PCM data is routed via the DSP. The host CPU in this use case
3308c2ecf20Sopenharmony_ciis only used for control and can sleep during the runtime of the stream.
3318c2ecf20Sopenharmony_ci
3328c2ecf20Sopenharmony_ciThe host can control the hostless link either by :-
3338c2ecf20Sopenharmony_ci
3348c2ecf20Sopenharmony_ci 1. Configuring the link as a CODEC <-> CODEC style link. In this case the link
3358c2ecf20Sopenharmony_ci    is enabled or disabled by the state of the DAPM graph. This usually means
3368c2ecf20Sopenharmony_ci    there is a mixer control that can be used to connect or disconnect the path
3378c2ecf20Sopenharmony_ci    between both DAIs.
3388c2ecf20Sopenharmony_ci
3398c2ecf20Sopenharmony_ci 2. Hostless FE. This FE has a virtual connection to the BE DAI links on the DAPM
3408c2ecf20Sopenharmony_ci    graph. Control is then carried out by the FE as regular PCM operations.
3418c2ecf20Sopenharmony_ci    This method gives more control over the DAI links, but requires much more
3428c2ecf20Sopenharmony_ci    userspace code to control the link. Its recommended to use CODEC<->CODEC
3438c2ecf20Sopenharmony_ci    unless your HW needs more fine grained sequencing of the PCM ops.
3448c2ecf20Sopenharmony_ci
3458c2ecf20Sopenharmony_ci
3468c2ecf20Sopenharmony_ciCODEC <-> CODEC link
3478c2ecf20Sopenharmony_ci--------------------
3488c2ecf20Sopenharmony_ci
3498c2ecf20Sopenharmony_ciThis DAI link is enabled when DAPM detects a valid path within the DAPM graph.
3508c2ecf20Sopenharmony_ciThe machine driver sets some additional parameters to the DAI link i.e.
3518c2ecf20Sopenharmony_ci::
3528c2ecf20Sopenharmony_ci
3538c2ecf20Sopenharmony_ci  static const struct snd_soc_pcm_stream dai_params = {
3548c2ecf20Sopenharmony_ci	.formats = SNDRV_PCM_FMTBIT_S32_LE,
3558c2ecf20Sopenharmony_ci	.rate_min = 8000,
3568c2ecf20Sopenharmony_ci	.rate_max = 8000,
3578c2ecf20Sopenharmony_ci	.channels_min = 2,
3588c2ecf20Sopenharmony_ci	.channels_max = 2,
3598c2ecf20Sopenharmony_ci  };
3608c2ecf20Sopenharmony_ci
3618c2ecf20Sopenharmony_ci  static struct snd_soc_dai_link dais[] = {
3628c2ecf20Sopenharmony_ci	< ... more DAI links above ... >
3638c2ecf20Sopenharmony_ci	{
3648c2ecf20Sopenharmony_ci		.name = "MODEM",
3658c2ecf20Sopenharmony_ci		.stream_name = "MODEM",
3668c2ecf20Sopenharmony_ci		.cpu_dai_name = "dai2",
3678c2ecf20Sopenharmony_ci		.codec_dai_name = "modem-aif1",
3688c2ecf20Sopenharmony_ci		.codec_name = "modem",
3698c2ecf20Sopenharmony_ci		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
3708c2ecf20Sopenharmony_ci				| SND_SOC_DAIFMT_CBM_CFM,
3718c2ecf20Sopenharmony_ci		.params = &dai_params,
3728c2ecf20Sopenharmony_ci	}
3738c2ecf20Sopenharmony_ci	< ... more DAI links here ... >
3748c2ecf20Sopenharmony_ci
3758c2ecf20Sopenharmony_ciThese parameters are used to configure the DAI hw_params() when DAPM detects a
3768c2ecf20Sopenharmony_civalid path and then calls the PCM operations to start the link. DAPM will also
3778c2ecf20Sopenharmony_cicall the appropriate PCM operations to disable the DAI when the path is no
3788c2ecf20Sopenharmony_cilonger valid.
3798c2ecf20Sopenharmony_ci
3808c2ecf20Sopenharmony_ci
3818c2ecf20Sopenharmony_ciHostless FE
3828c2ecf20Sopenharmony_ci-----------
3838c2ecf20Sopenharmony_ci
3848c2ecf20Sopenharmony_ciThe DAI link(s) are enabled by a FE that does not read or write any PCM data.
3858c2ecf20Sopenharmony_ciThis means creating a new FE that is connected with a virtual path to both
3868c2ecf20Sopenharmony_ciDAI links. The DAI links will be started when the FE PCM is started and stopped
3878c2ecf20Sopenharmony_ciwhen the FE PCM is stopped. Note that the FE PCM cannot read or write data in
3888c2ecf20Sopenharmony_cithis configuration.
389