-
Notifications
You must be signed in to change notification settings - Fork 140
Add support for hostless and DAIless pipelines #5609
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for hostless and DAIless pipelines #5609
Conversation
|
I tested this PR with other echo ref capture related PRs (thesofproject/sof#10329 and thesofproject/sof#10387), it works perfectly. |
44a47e3 to
6c97700
Compare
6c97700 to
640894b
Compare
lgirdwood
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some minor opens
sound/soc/intel/boards/sof_sdw.c
Outdated
| { | ||
| struct device *dev = card->dev; | ||
| int ret; | ||
| char *name = devm_kasprintf(dev, GFP_KERNEL, "EchoRef_virtual_DAI"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will this always be echo ref or can it also be a capture device for recording playback ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is set up as as capture device for recording playback by default f playback is active. If playback is not active, it produces silence
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, so could we make a more generic/meaningful name so that users will know what to do with it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks too fragile to me.
It just happens that we use a tone/signal generator (which generates 0) to feed to an EchoRef capture PCM, but the concept is defined in topology.
Do you have topology PR to see how this looks like?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here you go @ujfalusi. This is what an echo ref topology looks like

There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, so could we make a more generic/meaningful name so that users will know what to do with it.
@lgirdwood how about "LoopbackCapture_virtual_DAI"?
sound/soc/sof/sof-audio.c
Outdated
| goto sink_prepare; | ||
|
|
||
| /* skip aggregated DAIs */ | ||
| if(is_aggregated_dai(swidget)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
ujfalusi
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ranj063, I don't think I understand all the details and how this changes the whole walking logic, I trust that the logic is solid.
The last patch revealed (to commit message) how the direction comes to be used...
I suppose it could be possible to add a simple tone generator now:
virtual DAI -> tone generator -> Host (tone capture)
but it is not, isn't it? We would need to change the machine driver and other things to match with the topology change?
I'm not sure if there is a more dynamic, topology driven way to achieve the virtual DAI concept, which would give really nice user feature at the end.
sound/soc/intel/boards/sof_sdw.c
Outdated
| { | ||
| struct device *dev = card->dev; | ||
| int ret; | ||
| char *name = devm_kasprintf(dev, GFP_KERNEL, "EchoRef_virtual_DAI"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks too fragile to me.
It just happens that we use a tone/signal generator (which generates 0) to feed to an EchoRef capture PCM, but the concept is defined in topology.
Do you have topology PR to see how this looks like?
| ret = asoc_sdw_init_simple_dai_link(dev, *dai_links, be_id, name, | ||
| 0, 1, "snd-soc-dummy-dai", "dummy", | ||
| snd_soc_dummy_dlc.name, snd_soc_dummy_dlc.dai_name, | ||
| 1, NULL, NULL); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only sdw can have this feature, HDA or SSP machines never?
We cannot add to topology a tone generator for example at will, but we need to change the kernel as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In theory the same logic would work for all machines and yes you would need the machine driver change in order to use it. But in the case of SSP, we dont need this. We can use the Loopback mode like we've always used. So maybe just the HDA machine change would be enough
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
HDA and SSP not priority.
| out_fmt = &available_fmt->output_pin_fmts[0].audio_fmt; | ||
|
|
||
| /* copy output format */ | ||
| memcpy(&process->base_config.audio_fmt, out_fmt, sizeof(*out_fmt)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what will happen if the fe_parmas and the first output_fmt of the module does not match?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You'll end up with an error that out format match wasnt found on line 2802 isnt it?
| #include "sof-audio.h" | ||
| #include "ops.h" | ||
|
|
||
| /* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does one 'start' such a tone generator playback? There is no PCM device involved, so there must be a kcontrol switch which forces the system to motion.
How?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a PCM with the tone generator pipeline. It serves the purpose of propragating the hw_params and triggers to the list of connected DAPM widgets. A kcontrol is a possibility but without a PCM, it wont be easy to know which widgets to set up or even how to the hw_params for the FE DAI and BE DAI and the codec. The PCM is a shortcut in this case to achieve that functionality
sound/soc/sof/sof-audio.c
Outdated
| { | ||
| return (WIDGET_IS_DAI(swidget->id) && | ||
| isdigit(swidget->widget->name[strlen(swidget->widget->name) - 1]) && | ||
| swidget->widget->name[strlen(swidget->widget->name) - 1] != '0'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how did this worked then currently if we should not be dealing with the .[1..9] DAIs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
today it works because we stop traversing the path when we see a virtual widget. So if you look at the aggregated DAI alh-copier-SDW1.Playback.1 in the topology I shared in another comment, it is preceded by a virtual widget. So we see that and ignore everything below it. But now for tone and echo ref we want to go down the path from either an aggregated DAI or a virtual widget to the sink components in the path.
@ujfalusi yes this is all you need in topology and it will work. No need to change anything for tone playback. |
640894b to
ebdfe34
Compare
Align with the firmware and add the missing token for pipeline kcps. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
ebdfe34 to
43616af
Compare
singalsu
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This patch version worked OK with firmware and topology patches to create echo reference capture PCMs.
43616af to
779773c
Compare
779773c to
57524a2
Compare
|
dropped support for hostless playback for now> will be added later |
ujfalusi
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| if (ret) | ||
| return ret; | ||
|
|
||
| (*dai_links)++; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how this will work with existing topologies and with function topology?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It shouldnt matter if we use function topologies right? We just have a single machine even in that case right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the function topology parsing will fall back to monolithic when it faces with a link of unknown origin/no fragment.
We have now patch to make this not fail when there is no monolithic topology defined, but this (I think) will eventually disable the function topologies?
I'm not sure, but this is my feeling.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
best to comment what the assumption will be here regarding topology.
| /* allocate BE dailinks */ | ||
| num_links = sdw_be_num + ssp_num + dmic_num + hdmi_num + bt_num; | ||
| /* allocate BE dailinks, add an extra DAI link for echo reference capture */ | ||
| num_links = sdw_be_num + ssp_num + dmic_num + hdmi_num + bt_num + 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this is also a chicken and egg problem... This is purely topology construct, but we don't know if the topology have virtual DAI before we pick and parse the topology and for that we need the links in place if the topology do have this defined, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
right
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, lets capture this behavior in the comments.
| struct sof_ipc4_msg msg; | ||
| bool skip_during_fe_trigger; | ||
| bool direction_valid; | ||
| u32 direction; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should it be documented what values are valid for direction, like what 0 means, what 1 means, is there a direction == 2...10?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ujfalusi these come directly from topology, so are checked for validity there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so, the value for kernel does not matter, only they should match?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can add that context to the comment. Can complain too if out of range.
| SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); | ||
| out_ref_valid_bits = | ||
| SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg); | ||
| out_ref_type = sof_ipc4_fmt_cfg_to_type(in_fmt->fmt_cfg); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and to add I have this PR for some time which touches the same code and fixes issue when not all parameters are changed by a process module:
#5442
57524a2 to
2b625b2
Compare
2b625b2 to
3e91b71
Compare
lgirdwood
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, on my side it may benefit from more comments where expectations/behaviours are unclear.
| ret = asoc_sdw_init_simple_dai_link(dev, *dai_links, be_id, name, | ||
| 0, 1, "snd-soc-dummy-dai", "dummy", | ||
| snd_soc_dummy_dlc.name, snd_soc_dummy_dlc.dai_name, | ||
| 1, NULL, NULL); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
HDA and SSP not priority.
| if (ret) | ||
| return ret; | ||
|
|
||
| (*dai_links)++; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
best to comment what the assumption will be here regarding topology.
| /* allocate BE dailinks */ | ||
| num_links = sdw_be_num + ssp_num + dmic_num + hdmi_num + bt_num; | ||
| /* allocate BE dailinks, add an extra DAI link for echo reference capture */ | ||
| num_links = sdw_be_num + ssp_num + dmic_num + hdmi_num + bt_num + 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, lets capture this behavior in the comments.
| struct sof_ipc4_msg msg; | ||
| bool skip_during_fe_trigger; | ||
| bool direction_valid; | ||
| u32 direction; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can add that context to the comment. Can complain too if out of range.
Add a DAI link for loopback capture as the last link to make sure the other DAI link ID's remain unaffected. It serves as a dummy DAI link to enable echo reference capture in the SDW topologies which do not have an actual backend capture DAI. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Parse the pipeline direction from topology. The direction_valid token is required for backward-compatibility with older topologies that may not have the direction set for pipelines. This will be used when setting up pipelines to check if a pipeline is in the same direction as the requested params and skip those in the opposite direction like in the case of echo reference capture pipelines during playback. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
…ut pins A tone generator module can be a type of processing module with no input pins. Adjust the logic to set the reference params for selecting output format and the basecfg format based on the output format. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Aggregated DAI widgets exist in topology for representation and are not actually initialized in the firmware. But in preparation for using this as a virtual DAI for loopback capture, make sure that we can traverse the path from an aggregated DAI widget to the host widget. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
An example of a DAI-less loopback pipeline would be the echo reference capture in the speaker playback path. This pipeline is set up as follows: Host(Playback) -> mixin -> mixout -> gain -> module-copier -> DAI | V Host(Capture) <- Process module <- virtual DAI In the above example, the virtual DAI exploits the concept of an aggregated DAI (one with a non-zero DAI ID) in topology to enable this pipeline to work with DPCM. A virtual DAI is a DAI widget with a non-zero DAI ID and hence is skipped when traversing the list of DAPM widgets during widget prepare/set/up/free/unprepare. The process module in the above pipeline generates 0's that are captured by the echo reference PCM. When the playback path is active, the process module acts as a passthrough module to allow the playback samples to be passthrough to the capture host. In order for these pipelines to work properly, the logic for setting/preparing/freeing/unpreparing the widgets needs to be amended to make sure that only the widgets that are in the pipeline in the same direction as the PCM being started are set up. For example, when the playback PCM is started, the capture pipeline widgets also show up in the list of connected DAPM widgets but they shouldn't be set up yet because the echo reference capture PCM hasn't been started yet. Alternatively, when the echo reference capture PCM is started, the playback pipeline widgets should not be setup. Finally, the last step needed to put this all together is the set the routes for widgets connecting the playback and the capture pipelines when both are active. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
3e91b71 to
ab6ff22
Compare
|
SOFCI TEST |
1 similar comment
|
SOFCI TEST |
No description provided.