162306a36Sopenharmony_ci===========
262306a36Sopenharmony_ciDynamic PCM
362306a36Sopenharmony_ci===========
462306a36Sopenharmony_ci
562306a36Sopenharmony_ciDescription
662306a36Sopenharmony_ci===========
762306a36Sopenharmony_ci
862306a36Sopenharmony_ciDynamic PCM allows an ALSA PCM device to digitally route its PCM audio to
962306a36Sopenharmony_civarious digital endpoints during the PCM stream runtime. e.g. PCM0 can route
1062306a36Sopenharmony_cidigital audio to I2S DAI0, I2S DAI1 or PDM DAI2. This is useful for on SoC DSP
1162306a36Sopenharmony_cidrivers that expose several ALSA PCMs and can route to multiple DAIs.
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ciThe DPCM runtime routing is determined by the ALSA mixer settings in the same
1462306a36Sopenharmony_ciway as the analog signal is routed in an ASoC codec driver. DPCM uses a DAPM
1562306a36Sopenharmony_cigraph representing the DSP internal audio paths and uses the mixer settings to
1662306a36Sopenharmony_cidetermine the path used by each ALSA PCM.
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ciDPCM re-uses all the existing component codec, platform and DAI drivers without
1962306a36Sopenharmony_ciany modifications.
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ciPhone Audio System with SoC based DSP
2362306a36Sopenharmony_ci-------------------------------------
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ciConsider the following phone audio subsystem. This will be used in this
2662306a36Sopenharmony_cidocument for all examples :-
2762306a36Sopenharmony_ci::
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci  | Front End PCMs    |  SoC DSP  | Back End DAIs | Audio devices |
3062306a36Sopenharmony_ci  
3162306a36Sopenharmony_ci                      *************
3262306a36Sopenharmony_ci  PCM0 <------------> *           * <----DAI0-----> Codec Headset
3362306a36Sopenharmony_ci                      *           *
3462306a36Sopenharmony_ci  PCM1 <------------> *           * <----DAI1-----> Codec Speakers
3562306a36Sopenharmony_ci                      *   DSP     *
3662306a36Sopenharmony_ci  PCM2 <------------> *           * <----DAI2-----> MODEM
3762306a36Sopenharmony_ci                      *           *
3862306a36Sopenharmony_ci  PCM3 <------------> *           * <----DAI3-----> BT
3962306a36Sopenharmony_ci                      *           *
4062306a36Sopenharmony_ci                      *           * <----DAI4-----> DMIC
4162306a36Sopenharmony_ci                      *           *
4262306a36Sopenharmony_ci                      *           * <----DAI5-----> FM
4362306a36Sopenharmony_ci                      *************
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ciThis diagram shows a simple smart phone audio subsystem. It supports Bluetooth,
4662306a36Sopenharmony_ciFM digital radio, Speakers, Headset Jack, digital microphones and cellular
4762306a36Sopenharmony_cimodem. This sound card exposes 4 DSP front end (FE) ALSA PCM devices and
4862306a36Sopenharmony_cisupports 6 back end (BE) DAIs. Each FE PCM can digitally route audio data to any
4962306a36Sopenharmony_ciof the BE DAIs. The FE PCM devices can also route audio to more than 1 BE DAI.
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ciExample - DPCM Switching playback from DAI0 to DAI1
5462306a36Sopenharmony_ci---------------------------------------------------
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ciAudio is being played to the Headset. After a while the user removes the headset
5762306a36Sopenharmony_ciand audio continues playing on the speakers.
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ciPlayback on PCM0 to Headset would look like :-
6062306a36Sopenharmony_ci::
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci                      *************
6362306a36Sopenharmony_ci  PCM0 <============> *           * <====DAI0=====> Codec Headset
6462306a36Sopenharmony_ci                      *           *
6562306a36Sopenharmony_ci  PCM1 <------------> *           * <----DAI1-----> Codec Speakers
6662306a36Sopenharmony_ci                      *   DSP     *
6762306a36Sopenharmony_ci  PCM2 <------------> *           * <----DAI2-----> MODEM
6862306a36Sopenharmony_ci                      *           *
6962306a36Sopenharmony_ci  PCM3 <------------> *           * <----DAI3-----> BT
7062306a36Sopenharmony_ci                      *           *
7162306a36Sopenharmony_ci                      *           * <----DAI4-----> DMIC
7262306a36Sopenharmony_ci                      *           *
7362306a36Sopenharmony_ci                      *           * <----DAI5-----> FM
7462306a36Sopenharmony_ci                      *************
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ciThe headset is removed from the jack by user so the speakers must now be used :-
7762306a36Sopenharmony_ci::
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci                      *************
8062306a36Sopenharmony_ci  PCM0 <============> *           * <----DAI0-----> Codec Headset
8162306a36Sopenharmony_ci                      *           *
8262306a36Sopenharmony_ci  PCM1 <------------> *           * <====DAI1=====> Codec Speakers
8362306a36Sopenharmony_ci                      *   DSP     *
8462306a36Sopenharmony_ci  PCM2 <------------> *           * <----DAI2-----> MODEM
8562306a36Sopenharmony_ci                      *           *
8662306a36Sopenharmony_ci  PCM3 <------------> *           * <----DAI3-----> BT
8762306a36Sopenharmony_ci                      *           *
8862306a36Sopenharmony_ci                      *           * <----DAI4-----> DMIC
8962306a36Sopenharmony_ci                      *           *
9062306a36Sopenharmony_ci                      *           * <----DAI5-----> FM
9162306a36Sopenharmony_ci                      *************
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ciThe audio driver processes this as follows :-
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci1. Machine driver receives Jack removal event.
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci2. Machine driver OR audio HAL disables the Headset path.
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci3. DPCM runs the PCM trigger(stop), hw_free(), shutdown() operations on DAI0
10062306a36Sopenharmony_ci   for headset since the path is now disabled.
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci4. Machine driver or audio HAL enables the speaker path.
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci5. DPCM runs the PCM ops for startup(), hw_params(), prepare() and
10562306a36Sopenharmony_ci   trigger(start) for DAI1 Speakers since the path is enabled.
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ciIn this example, the machine driver or userspace audio HAL can alter the routing
10862306a36Sopenharmony_ciand then DPCM will take care of managing the DAI PCM operations to either bring
10962306a36Sopenharmony_cithe link up or down. Audio playback does not stop during this transition.
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ciDPCM machine driver
11462306a36Sopenharmony_ci===================
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_ciThe DPCM enabled ASoC machine driver is similar to normal machine drivers
11762306a36Sopenharmony_ciexcept that we also have to :-
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci1. Define the FE and BE DAI links.
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci2. Define any FE/BE PCM operations.
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci3. Define widget graph connections.
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ciFE and BE DAI links
12762306a36Sopenharmony_ci-------------------
12862306a36Sopenharmony_ci::
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ci  | Front End PCMs    |  SoC DSP  | Back End DAIs | Audio devices |
13162306a36Sopenharmony_ci  
13262306a36Sopenharmony_ci                      *************
13362306a36Sopenharmony_ci  PCM0 <------------> *           * <----DAI0-----> Codec Headset
13462306a36Sopenharmony_ci                      *           *
13562306a36Sopenharmony_ci  PCM1 <------------> *           * <----DAI1-----> Codec Speakers
13662306a36Sopenharmony_ci                      *   DSP     *
13762306a36Sopenharmony_ci  PCM2 <------------> *           * <----DAI2-----> MODEM
13862306a36Sopenharmony_ci                      *           *
13962306a36Sopenharmony_ci  PCM3 <------------> *           * <----DAI3-----> BT
14062306a36Sopenharmony_ci                      *           *
14162306a36Sopenharmony_ci                      *           * <----DAI4-----> DMIC
14262306a36Sopenharmony_ci                      *           *
14362306a36Sopenharmony_ci                      *           * <----DAI5-----> FM
14462306a36Sopenharmony_ci                      *************
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ciFor the example above we have to define 4 FE DAI links and 6 BE DAI links. The
14762306a36Sopenharmony_ciFE DAI links are defined as follows :-
14862306a36Sopenharmony_ci::
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_ci  static struct snd_soc_dai_link machine_dais[] = {
15162306a36Sopenharmony_ci	{
15262306a36Sopenharmony_ci		.name = "PCM0 System",
15362306a36Sopenharmony_ci		.stream_name = "System Playback",
15462306a36Sopenharmony_ci		.cpu_dai_name = "System Pin",
15562306a36Sopenharmony_ci		.platform_name = "dsp-audio",
15662306a36Sopenharmony_ci		.codec_name = "snd-soc-dummy",
15762306a36Sopenharmony_ci		.codec_dai_name = "snd-soc-dummy-dai",
15862306a36Sopenharmony_ci		.dynamic = 1,
15962306a36Sopenharmony_ci		.trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
16062306a36Sopenharmony_ci		.dpcm_playback = 1,
16162306a36Sopenharmony_ci	},
16262306a36Sopenharmony_ci	.....< other FE and BE DAI links here >
16362306a36Sopenharmony_ci  };
16462306a36Sopenharmony_ci
16562306a36Sopenharmony_ciThis FE DAI link is pretty similar to a regular DAI link except that we also
16662306a36Sopenharmony_ciset the DAI link to a DPCM FE with the ``dynamic = 1``. The supported FE stream
16762306a36Sopenharmony_cidirections should also be set with the ``dpcm_playback`` and ``dpcm_capture``
16862306a36Sopenharmony_ciflags. There is also an option to specify the ordering of the trigger call for
16962306a36Sopenharmony_cieach FE. This allows the ASoC core to trigger the DSP before or after the other
17062306a36Sopenharmony_cicomponents (as some DSPs have strong requirements for the ordering DAI/DSP
17162306a36Sopenharmony_cistart and stop sequences).
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_ciThe FE DAI above sets the codec and code DAIs to dummy devices since the BE is
17462306a36Sopenharmony_cidynamic and will change depending on runtime config.
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_ciThe BE DAIs are configured as follows :-
17762306a36Sopenharmony_ci::
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_ci  static struct snd_soc_dai_link machine_dais[] = {
18062306a36Sopenharmony_ci	.....< FE DAI links here >
18162306a36Sopenharmony_ci	{
18262306a36Sopenharmony_ci		.name = "Codec Headset",
18362306a36Sopenharmony_ci		.cpu_dai_name = "ssp-dai.0",
18462306a36Sopenharmony_ci		.platform_name = "snd-soc-dummy",
18562306a36Sopenharmony_ci		.no_pcm = 1,
18662306a36Sopenharmony_ci		.codec_name = "rt5640.0-001c",
18762306a36Sopenharmony_ci		.codec_dai_name = "rt5640-aif1",
18862306a36Sopenharmony_ci		.ignore_suspend = 1,
18962306a36Sopenharmony_ci		.ignore_pmdown_time = 1,
19062306a36Sopenharmony_ci		.be_hw_params_fixup = hswult_ssp0_fixup,
19162306a36Sopenharmony_ci		.ops = &haswell_ops,
19262306a36Sopenharmony_ci		.dpcm_playback = 1,
19362306a36Sopenharmony_ci		.dpcm_capture = 1,
19462306a36Sopenharmony_ci	},
19562306a36Sopenharmony_ci	.....< other BE DAI links here >
19662306a36Sopenharmony_ci  };
19762306a36Sopenharmony_ci
19862306a36Sopenharmony_ciThis BE DAI link connects DAI0 to the codec (in this case RT5460 AIF1). It sets
19962306a36Sopenharmony_cithe ``no_pcm`` flag to mark it has a BE and sets flags for supported stream
20062306a36Sopenharmony_cidirections using ``dpcm_playback`` and ``dpcm_capture`` above.
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_ciThe BE has also flags set for ignoring suspend and PM down time. This allows
20362306a36Sopenharmony_cithe BE to work in a hostless mode where the host CPU is not transferring data
20462306a36Sopenharmony_cilike a BT phone call :-
20562306a36Sopenharmony_ci::
20662306a36Sopenharmony_ci
20762306a36Sopenharmony_ci                      *************
20862306a36Sopenharmony_ci  PCM0 <------------> *           * <----DAI0-----> Codec Headset
20962306a36Sopenharmony_ci                      *           *
21062306a36Sopenharmony_ci  PCM1 <------------> *           * <----DAI1-----> Codec Speakers
21162306a36Sopenharmony_ci                      *   DSP     *
21262306a36Sopenharmony_ci  PCM2 <------------> *           * <====DAI2=====> MODEM
21362306a36Sopenharmony_ci                      *           *
21462306a36Sopenharmony_ci  PCM3 <------------> *           * <====DAI3=====> BT
21562306a36Sopenharmony_ci                      *           *
21662306a36Sopenharmony_ci                      *           * <----DAI4-----> DMIC
21762306a36Sopenharmony_ci                      *           *
21862306a36Sopenharmony_ci                      *           * <----DAI5-----> FM
21962306a36Sopenharmony_ci                      *************
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_ciThis allows the host CPU to sleep while the DSP, MODEM DAI and the BT DAI are
22262306a36Sopenharmony_cistill in operation.
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_ciA BE DAI link can also set the codec to a dummy device if the codec is a device
22562306a36Sopenharmony_cithat is managed externally.
22662306a36Sopenharmony_ci
22762306a36Sopenharmony_ciLikewise a BE DAI can also set a dummy cpu DAI if the CPU DAI is managed by the
22862306a36Sopenharmony_ciDSP firmware.
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ci
23162306a36Sopenharmony_ciFE/BE PCM operations
23262306a36Sopenharmony_ci--------------------
23362306a36Sopenharmony_ci
23462306a36Sopenharmony_ciThe BE above also exports some PCM operations and a ``fixup`` callback. The fixup
23562306a36Sopenharmony_cicallback is used by the machine driver to (re)configure the DAI based upon the
23662306a36Sopenharmony_ciFE hw params. i.e. the DSP may perform SRC or ASRC from the FE to BE.
23762306a36Sopenharmony_ci
23862306a36Sopenharmony_cie.g. DSP converts all FE hw params to run at fixed rate of 48k, 16bit, stereo for
23962306a36Sopenharmony_ciDAI0. This means all FE hw_params have to be fixed in the machine driver for
24062306a36Sopenharmony_ciDAI0 so that the DAI is running at desired configuration regardless of the FE
24162306a36Sopenharmony_ciconfiguration.
24262306a36Sopenharmony_ci::
24362306a36Sopenharmony_ci
24462306a36Sopenharmony_ci  static int dai0_fixup(struct snd_soc_pcm_runtime *rtd,
24562306a36Sopenharmony_ci			struct snd_pcm_hw_params *params)
24662306a36Sopenharmony_ci  {
24762306a36Sopenharmony_ci	struct snd_interval *rate = hw_param_interval(params,
24862306a36Sopenharmony_ci			SNDRV_PCM_HW_PARAM_RATE);
24962306a36Sopenharmony_ci	struct snd_interval *channels = hw_param_interval(params,
25062306a36Sopenharmony_ci						SNDRV_PCM_HW_PARAM_CHANNELS);
25162306a36Sopenharmony_ci
25262306a36Sopenharmony_ci	/* The DSP will convert the FE rate to 48k, stereo */
25362306a36Sopenharmony_ci	rate->min = rate->max = 48000;
25462306a36Sopenharmony_ci	channels->min = channels->max = 2;
25562306a36Sopenharmony_ci
25662306a36Sopenharmony_ci	/* set DAI0 to 16 bit */
25762306a36Sopenharmony_ci	params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);
25862306a36Sopenharmony_ci	return 0;
25962306a36Sopenharmony_ci  }
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_ciThe other PCM operation are the same as for regular DAI links. Use as necessary.
26262306a36Sopenharmony_ci
26362306a36Sopenharmony_ci
26462306a36Sopenharmony_ciWidget graph connections
26562306a36Sopenharmony_ci------------------------
26662306a36Sopenharmony_ci
26762306a36Sopenharmony_ciThe BE DAI links will normally be connected to the graph at initialisation time
26862306a36Sopenharmony_ciby the ASoC DAPM core. However, if the BE codec or BE DAI is a dummy then this
26962306a36Sopenharmony_cihas to be set explicitly in the driver :-
27062306a36Sopenharmony_ci::
27162306a36Sopenharmony_ci
27262306a36Sopenharmony_ci  /* BE for codec Headset -  DAI0 is dummy and managed by DSP FW */
27362306a36Sopenharmony_ci  {"DAI0 CODEC IN", NULL, "AIF1 Capture"},
27462306a36Sopenharmony_ci  {"AIF1 Playback", NULL, "DAI0 CODEC OUT"},
27562306a36Sopenharmony_ci
27662306a36Sopenharmony_ci
27762306a36Sopenharmony_ciWriting a DPCM DSP driver
27862306a36Sopenharmony_ci=========================
27962306a36Sopenharmony_ci
28062306a36Sopenharmony_ciThe DPCM DSP driver looks much like a standard platform class ASoC driver
28162306a36Sopenharmony_cicombined with elements from a codec class driver. A DSP platform driver must
28262306a36Sopenharmony_ciimplement :-
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_ci1. Front End PCM DAIs - i.e. struct snd_soc_dai_driver.
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_ci2. DAPM graph showing DSP audio routing from FE DAIs to BEs.
28762306a36Sopenharmony_ci
28862306a36Sopenharmony_ci3. DAPM widgets from DSP graph.
28962306a36Sopenharmony_ci
29062306a36Sopenharmony_ci4. Mixers for gains, routing, etc.
29162306a36Sopenharmony_ci
29262306a36Sopenharmony_ci5. DMA configuration.
29362306a36Sopenharmony_ci
29462306a36Sopenharmony_ci6. BE AIF widgets.
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_ciItems 6 is important for routing the audio outside of the DSP. AIF need to be
29762306a36Sopenharmony_cidefined for each BE and each stream direction. e.g for BE DAI0 above we would
29862306a36Sopenharmony_cihave :-
29962306a36Sopenharmony_ci::
30062306a36Sopenharmony_ci
30162306a36Sopenharmony_ci  SND_SOC_DAPM_AIF_IN("DAI0 RX", NULL, 0, SND_SOC_NOPM, 0, 0),
30262306a36Sopenharmony_ci  SND_SOC_DAPM_AIF_OUT("DAI0 TX", NULL, 0, SND_SOC_NOPM, 0, 0),
30362306a36Sopenharmony_ci
30462306a36Sopenharmony_ciThe BE AIF are used to connect the DSP graph to the graphs for the other
30562306a36Sopenharmony_cicomponent drivers (e.g. codec graph).
30662306a36Sopenharmony_ci
30762306a36Sopenharmony_ci
30862306a36Sopenharmony_ciHostless PCM streams
30962306a36Sopenharmony_ci====================
31062306a36Sopenharmony_ci
31162306a36Sopenharmony_ciA hostless PCM stream is a stream that is not routed through the host CPU. An
31262306a36Sopenharmony_ciexample of this would be a phone call from handset to modem.
31362306a36Sopenharmony_ci::
31462306a36Sopenharmony_ci
31562306a36Sopenharmony_ci                      *************
31662306a36Sopenharmony_ci  PCM0 <------------> *           * <----DAI0-----> Codec Headset
31762306a36Sopenharmony_ci                      *           *
31862306a36Sopenharmony_ci  PCM1 <------------> *           * <====DAI1=====> Codec Speakers/Mic
31962306a36Sopenharmony_ci                      *   DSP     *
32062306a36Sopenharmony_ci  PCM2 <------------> *           * <====DAI2=====> MODEM
32162306a36Sopenharmony_ci                      *           *
32262306a36Sopenharmony_ci  PCM3 <------------> *           * <----DAI3-----> BT
32362306a36Sopenharmony_ci                      *           *
32462306a36Sopenharmony_ci                      *           * <----DAI4-----> DMIC
32562306a36Sopenharmony_ci                      *           *
32662306a36Sopenharmony_ci                      *           * <----DAI5-----> FM
32762306a36Sopenharmony_ci                      *************
32862306a36Sopenharmony_ci
32962306a36Sopenharmony_ciIn this case the PCM data is routed via the DSP. The host CPU in this use case
33062306a36Sopenharmony_ciis only used for control and can sleep during the runtime of the stream.
33162306a36Sopenharmony_ci
33262306a36Sopenharmony_ciThe host can control the hostless link either by :-
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_ci 1. Configuring the link as a CODEC <-> CODEC style link. In this case the link
33562306a36Sopenharmony_ci    is enabled or disabled by the state of the DAPM graph. This usually means
33662306a36Sopenharmony_ci    there is a mixer control that can be used to connect or disconnect the path
33762306a36Sopenharmony_ci    between both DAIs.
33862306a36Sopenharmony_ci
33962306a36Sopenharmony_ci 2. Hostless FE. This FE has a virtual connection to the BE DAI links on the DAPM
34062306a36Sopenharmony_ci    graph. Control is then carried out by the FE as regular PCM operations.
34162306a36Sopenharmony_ci    This method gives more control over the DAI links, but requires much more
34262306a36Sopenharmony_ci    userspace code to control the link. Its recommended to use CODEC<->CODEC
34362306a36Sopenharmony_ci    unless your HW needs more fine grained sequencing of the PCM ops.
34462306a36Sopenharmony_ci
34562306a36Sopenharmony_ci
34662306a36Sopenharmony_ciCODEC <-> CODEC link
34762306a36Sopenharmony_ci--------------------
34862306a36Sopenharmony_ci
34962306a36Sopenharmony_ciThis DAI link is enabled when DAPM detects a valid path within the DAPM graph.
35062306a36Sopenharmony_ciThe machine driver sets some additional parameters to the DAI link i.e.
35162306a36Sopenharmony_ci::
35262306a36Sopenharmony_ci
35362306a36Sopenharmony_ci  static const struct snd_soc_pcm_stream dai_params = {
35462306a36Sopenharmony_ci	.formats = SNDRV_PCM_FMTBIT_S32_LE,
35562306a36Sopenharmony_ci	.rate_min = 8000,
35662306a36Sopenharmony_ci	.rate_max = 8000,
35762306a36Sopenharmony_ci	.channels_min = 2,
35862306a36Sopenharmony_ci	.channels_max = 2,
35962306a36Sopenharmony_ci  };
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_ci  static struct snd_soc_dai_link dais[] = {
36262306a36Sopenharmony_ci	< ... more DAI links above ... >
36362306a36Sopenharmony_ci	{
36462306a36Sopenharmony_ci		.name = "MODEM",
36562306a36Sopenharmony_ci		.stream_name = "MODEM",
36662306a36Sopenharmony_ci		.cpu_dai_name = "dai2",
36762306a36Sopenharmony_ci		.codec_dai_name = "modem-aif1",
36862306a36Sopenharmony_ci		.codec_name = "modem",
36962306a36Sopenharmony_ci		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
37062306a36Sopenharmony_ci				| SND_SOC_DAIFMT_CBM_CFM,
37162306a36Sopenharmony_ci		.params = &dai_params,
37262306a36Sopenharmony_ci	}
37362306a36Sopenharmony_ci	< ... more DAI links here ... >
37462306a36Sopenharmony_ci
37562306a36Sopenharmony_ciThese parameters are used to configure the DAI hw_params() when DAPM detects a
37662306a36Sopenharmony_civalid path and then calls the PCM operations to start the link. DAPM will also
37762306a36Sopenharmony_cicall the appropriate PCM operations to disable the DAI when the path is no
37862306a36Sopenharmony_cilonger valid.
37962306a36Sopenharmony_ci
38062306a36Sopenharmony_ci
38162306a36Sopenharmony_ciHostless FE
38262306a36Sopenharmony_ci-----------
38362306a36Sopenharmony_ci
38462306a36Sopenharmony_ciThe DAI link(s) are enabled by a FE that does not read or write any PCM data.
38562306a36Sopenharmony_ciThis means creating a new FE that is connected with a virtual path to both
38662306a36Sopenharmony_ciDAI links. The DAI links will be started when the FE PCM is started and stopped
38762306a36Sopenharmony_ciwhen the FE PCM is stopped. Note that the FE PCM cannot read or write data in
38862306a36Sopenharmony_cithis configuration.
389