^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) ===========
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) Dynamic PCM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) ===========
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) Description
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) ===========
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) Dynamic PCM allows an ALSA PCM device to digitally route its PCM audio to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) various digital endpoints during the PCM stream runtime. e.g. PCM0 can route
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) digital audio to I2S DAI0, I2S DAI1 or PDM DAI2. This is useful for on SoC DSP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) drivers that expose several ALSA PCMs and can route to multiple DAIs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) The DPCM runtime routing is determined by the ALSA mixer settings in the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) way as the analog signal is routed in an ASoC codec driver. DPCM uses a DAPM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) graph representing the DSP internal audio paths and uses the mixer settings to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) determine the path used by each ALSA PCM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) DPCM re-uses all the existing component codec, platform and DAI drivers without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) any modifications.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) Phone Audio System with SoC based DSP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) -------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) Consider the following phone audio subsystem. This will be used in this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) document for all examples :-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) ::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) | Front End PCMs | SoC DSP | Back End DAIs | Audio devices |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) *************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) PCM0 <------------> * * <----DAI0-----> Codec Headset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) PCM1 <------------> * * <----DAI1-----> Codec Speakers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * DSP *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) PCM2 <------------> * * <----DAI2-----> MODEM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) PCM3 <------------> * * <----DAI3-----> BT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * * <----DAI4-----> DMIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * * <----DAI5-----> FM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) *************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) This diagram shows a simple smart phone audio subsystem. It supports Bluetooth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) FM digital radio, Speakers, Headset Jack, digital microphones and cellular
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) modem. This sound card exposes 4 DSP front end (FE) ALSA PCM devices and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) supports 6 back end (BE) DAIs. Each FE PCM can digitally route audio data to any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) of the BE DAIs. The FE PCM devices can also route audio to more than 1 BE DAI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) Example - DPCM Switching playback from DAI0 to DAI1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) ---------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) Audio is being played to the Headset. After a while the user removes the headset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) and audio continues playing on the speakers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) Playback on PCM0 to Headset would look like :-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) ::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) *************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) PCM0 <============> * * <====DAI0=====> Codec Headset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) PCM1 <------------> * * <----DAI1-----> Codec Speakers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * DSP *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) PCM2 <------------> * * <----DAI2-----> MODEM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) PCM3 <------------> * * <----DAI3-----> BT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * * <----DAI4-----> DMIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * * <----DAI5-----> FM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) *************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) The headset is removed from the jack by user so the speakers must now be used :-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) ::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) *************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) PCM0 <============> * * <----DAI0-----> Codec Headset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) PCM1 <------------> * * <====DAI1=====> Codec Speakers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * DSP *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) PCM2 <------------> * * <----DAI2-----> MODEM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) PCM3 <------------> * * <----DAI3-----> BT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * * <----DAI4-----> DMIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * * <----DAI5-----> FM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) *************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) The audio driver processes this as follows :-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) 1. Machine driver receives Jack removal event.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) 2. Machine driver OR audio HAL disables the Headset path.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) 3. DPCM runs the PCM trigger(stop), hw_free(), shutdown() operations on DAI0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) for headset since the path is now disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 4. Machine driver or audio HAL enables the speaker path.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 5. DPCM runs the PCM ops for startup(), hw_params(), prepare() and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) trigger(start) for DAI1 Speakers since the path is enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) In this example, the machine driver or userspace audio HAL can alter the routing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) and then DPCM will take care of managing the DAI PCM operations to either bring
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) the link up or down. Audio playback does not stop during this transition.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) DPCM machine driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) ===================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) The DPCM enabled ASoC machine driver is similar to normal machine drivers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) except that we also have to :-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 1. Define the FE and BE DAI links.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 2. Define any FE/BE PCM operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 3. Define widget graph connections.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) FE and BE DAI links
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) -------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) ::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) | Front End PCMs | SoC DSP | Back End DAIs | Audio devices |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) *************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) PCM0 <------------> * * <----DAI0-----> Codec Headset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) PCM1 <------------> * * <----DAI1-----> Codec Speakers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * DSP *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) PCM2 <------------> * * <----DAI2-----> MODEM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) PCM3 <------------> * * <----DAI3-----> BT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * * <----DAI4-----> DMIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * * <----DAI5-----> FM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) *************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) For the example above we have to define 4 FE DAI links and 6 BE DAI links. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) FE DAI links are defined as follows :-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) ::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) static struct snd_soc_dai_link machine_dais[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) .name = "PCM0 System",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) .stream_name = "System Playback",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) .cpu_dai_name = "System Pin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) .platform_name = "dsp-audio",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) .codec_name = "snd-soc-dummy",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) .codec_dai_name = "snd-soc-dummy-dai",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) .dynamic = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) .dpcm_playback = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) .....< other FE and BE DAI links here >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) This FE DAI link is pretty similar to a regular DAI link except that we also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) set the DAI link to a DPCM FE with the ``dynamic = 1``. The supported FE stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) directions should also be set with the ``dpcm_playback`` and ``dpcm_capture``
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) flags. There is also an option to specify the ordering of the trigger call for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) each FE. This allows the ASoC core to trigger the DSP before or after the other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) components (as some DSPs have strong requirements for the ordering DAI/DSP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) start and stop sequences).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) The FE DAI above sets the codec and code DAIs to dummy devices since the BE is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) dynamic and will change depending on runtime config.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) The BE DAIs are configured as follows :-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) ::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) static struct snd_soc_dai_link machine_dais[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) .....< FE DAI links here >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) .name = "Codec Headset",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) .cpu_dai_name = "ssp-dai.0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) .platform_name = "snd-soc-dummy",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) .no_pcm = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) .codec_name = "rt5640.0-001c",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) .codec_dai_name = "rt5640-aif1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) .ignore_suspend = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) .ignore_pmdown_time = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) .be_hw_params_fixup = hswult_ssp0_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) .ops = &haswell_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) .dpcm_playback = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) .dpcm_capture = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) .....< other BE DAI links here >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) This BE DAI link connects DAI0 to the codec (in this case RT5460 AIF1). It sets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) the ``no_pcm`` flag to mark it has a BE and sets flags for supported stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) directions using ``dpcm_playback`` and ``dpcm_capture`` above.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) The BE has also flags set for ignoring suspend and PM down time. This allows
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) the BE to work in a hostless mode where the host CPU is not transferring data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) like a BT phone call :-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) ::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) *************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) PCM0 <------------> * * <----DAI0-----> Codec Headset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) * *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) PCM1 <------------> * * <----DAI1-----> Codec Speakers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * DSP *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) PCM2 <------------> * * <====DAI2=====> MODEM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) * *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) PCM3 <------------> * * <====DAI3=====> BT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * * <----DAI4-----> DMIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) * *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) * * <----DAI5-----> FM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) *************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) This allows the host CPU to sleep while the DSP, MODEM DAI and the BT DAI are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) still in operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) A BE DAI link can also set the codec to a dummy device if the codec is a device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) that is managed externally.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) Likewise a BE DAI can also set a dummy cpu DAI if the CPU DAI is managed by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) DSP firmware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) FE/BE PCM operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) --------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) The BE above also exports some PCM operations and a ``fixup`` callback. The fixup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) callback is used by the machine driver to (re)configure the DAI based upon the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) FE hw params. i.e. the DSP may perform SRC or ASRC from the FE to BE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) e.g. DSP converts all FE hw params to run at fixed rate of 48k, 16bit, stereo for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) DAI0. This means all FE hw_params have to be fixed in the machine driver for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) DAI0 so that the DAI is running at desired configuration regardless of the FE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) configuration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) ::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static int dai0_fixup(struct snd_soc_pcm_runtime *rtd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) struct snd_pcm_hw_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) struct snd_interval *rate = hw_param_interval(params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) SNDRV_PCM_HW_PARAM_RATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) struct snd_interval *channels = hw_param_interval(params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) SNDRV_PCM_HW_PARAM_CHANNELS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) /* The DSP will convert the FE rate to 48k, stereo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) rate->min = rate->max = 48000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) channels->min = channels->max = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) /* set DAI0 to 16 bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) The other PCM operation are the same as for regular DAI links. Use as necessary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) Widget graph connections
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) ------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) The BE DAI links will normally be connected to the graph at initialisation time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) by the ASoC DAPM core. However, if the BE codec or BE DAI is a dummy then this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) has to be set explicitly in the driver :-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) ::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) /* BE for codec Headset - DAI0 is dummy and managed by DSP FW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) {"DAI0 CODEC IN", NULL, "AIF1 Capture"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) {"AIF1 Playback", NULL, "DAI0 CODEC OUT"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) Writing a DPCM DSP driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) =========================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) The DPCM DSP driver looks much like a standard platform class ASoC driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) combined with elements from a codec class driver. A DSP platform driver must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) implement :-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 1. Front End PCM DAIs - i.e. struct snd_soc_dai_driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 2. DAPM graph showing DSP audio routing from FE DAIs to BEs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 3. DAPM widgets from DSP graph.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 4. Mixers for gains, routing, etc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 5. DMA configuration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 6. BE AIF widgets.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) Items 6 is important for routing the audio outside of the DSP. AIF need to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) defined for each BE and each stream direction. e.g for BE DAI0 above we would
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) have :-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) ::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) SND_SOC_DAPM_AIF_IN("DAI0 RX", NULL, 0, SND_SOC_NOPM, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) SND_SOC_DAPM_AIF_OUT("DAI0 TX", NULL, 0, SND_SOC_NOPM, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) The BE AIF are used to connect the DSP graph to the graphs for the other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) component drivers (e.g. codec graph).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) Hostless PCM streams
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) ====================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) A hostless PCM stream is a stream that is not routed through the host CPU. An
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) example of this would be a phone call from handset to modem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) ::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) *************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) PCM0 <------------> * * <----DAI0-----> Codec Headset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) * *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) PCM1 <------------> * * <====DAI1=====> Codec Speakers/Mic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) * DSP *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) PCM2 <------------> * * <====DAI2=====> MODEM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) * *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) PCM3 <------------> * * <----DAI3-----> BT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) * * <----DAI4-----> DMIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) * * <----DAI5-----> FM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) *************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) In this case the PCM data is routed via the DSP. The host CPU in this use case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) is only used for control and can sleep during the runtime of the stream.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) The host can control the hostless link either by :-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 1. Configuring the link as a CODEC <-> CODEC style link. In this case the link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) is enabled or disabled by the state of the DAPM graph. This usually means
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) there is a mixer control that can be used to connect or disconnect the path
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) between both DAIs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 2. Hostless FE. This FE has a virtual connection to the BE DAI links on the DAPM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) graph. Control is then carried out by the FE as regular PCM operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) This method gives more control over the DAI links, but requires much more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) userspace code to control the link. Its recommended to use CODEC<->CODEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) unless your HW needs more fine grained sequencing of the PCM ops.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) CODEC <-> CODEC link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) --------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) This DAI link is enabled when DAPM detects a valid path within the DAPM graph.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) The machine driver sets some additional parameters to the DAI link i.e.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) ::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) static const struct snd_soc_pcm_stream dai_params = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) .formats = SNDRV_PCM_FMTBIT_S32_LE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) .rate_min = 8000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) .rate_max = 8000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) .channels_min = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) .channels_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) static struct snd_soc_dai_link dais[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) < ... more DAI links above ... >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) .name = "MODEM",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) .stream_name = "MODEM",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) .cpu_dai_name = "dai2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) .codec_dai_name = "modem-aif1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) .codec_name = "modem",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) | SND_SOC_DAIFMT_CBM_CFM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) .params = &dai_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) < ... more DAI links here ... >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) These parameters are used to configure the DAI hw_params() when DAPM detects a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) valid path and then calls the PCM operations to start the link. DAPM will also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) call the appropriate PCM operations to disable the DAI when the path is no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) longer valid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) Hostless FE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) -----------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) The DAI link(s) are enabled by a FE that does not read or write any PCM data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) This means creating a new FE that is connected with a virtual path to both
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) DAI links. The DAI links will be started when the FE PCM is started and stopped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) when the FE PCM is stopped. Note that the FE PCM cannot read or write data in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) this configuration.