-
Notifications
You must be signed in to change notification settings - Fork 131
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
Introducing virtual FE #8
Changes from 1 commit
5017eda
0452dd4
188a191
b829c2b
bd1132f
f00e120
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1582,7 +1582,6 @@ static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream, | |
|
||
/* Create any new FE <--> BE connections */ | ||
for (i = 0; i < list->num_widgets; i++) { | ||
|
||
switch (list->widgets[i]->id) { | ||
case snd_soc_dapm_dai_in: | ||
if (stream != SNDRV_PCM_STREAM_PLAYBACK) | ||
|
@@ -2789,6 +2788,109 @@ int soc_dpcm_be_digital_mute(struct snd_soc_pcm_runtime *fe, int mute) | |
return 0; | ||
} | ||
|
||
/* | ||
* create a virtual FE DAI link which has no pcm device registered. | ||
* Virtual FE DAI links are used in hostless pipelines | ||
* to enable the codecs when the pipeline is triggered | ||
*/ | ||
int soc_dpcm_vfe_new(struct snd_soc_card *card, int index, | ||
const char *link_name, const char *cpu_dai_name, | ||
const char *platform_name, int stream_dir) | ||
{ | ||
struct snd_soc_dai_link *link; | ||
|
||
link = kzalloc(sizeof(*link), GFP_KERNEL); | ||
if (!link) | ||
return -ENOMEM; | ||
|
||
dev_dbg(card->dev, "ASoC: adding new virtual FE DAI link %s\n", | ||
link_name); | ||
|
||
/* define FE DAI link */ | ||
link->name = link_name; | ||
link->cpu_dai_name = cpu_dai_name; | ||
link->platform_name = platform_name; | ||
link->codec_name = "snd-soc-dummy"; | ||
link->codec_dai_name = "snd-soc-dummy-dai"; | ||
|
||
/* | ||
* Enabling both dynamic and no_pcm flags indicates the link is virtual | ||
* i.e. it is a FE dai link but without a registered pcm device | ||
*/ | ||
link->dynamic = 1; | ||
link->no_pcm = 1; | ||
|
||
/* enable playback */ | ||
if (stream_dir == SNDRV_PCM_STREAM_PLAYBACK) | ||
link->dpcm_playback = 1; | ||
|
||
/* enable capture */ | ||
if (stream_dir == SNDRV_PCM_STREAM_CAPTURE) | ||
link->dpcm_capture = 1; | ||
|
||
link->dobj.index = index; | ||
link->dobj.type = SND_SOC_DOBJ_DAI_LINK; | ||
|
||
/* add link to card dai link list */ | ||
snd_soc_add_dai_link(card, link); | ||
|
||
return 0; | ||
} | ||
EXPORT_SYMBOL_GPL(soc_dpcm_vfe_new); | ||
|
||
/* free virtual FE DAI link */ | ||
int soc_dpcm_vfe_free(struct snd_soc_card *card, const char *link_name) | ||
{ | ||
struct snd_soc_rtdcom_list *rtdcom1, *rtdcom2; | ||
struct snd_soc_pcm_runtime *rtd, *temp; | ||
struct snd_pcm_str *pstr; | ||
int stream_dir; | ||
|
||
list_for_each_entry_safe(rtd, temp, &card->rtd_list, list) { | ||
|
||
/* delete requested FE link */ | ||
if (!strcmp(rtd->dai_link->name, link_name)) { | ||
|
||
if (rtd->dai_link->dpcm_playback) | ||
stream_dir = SNDRV_PCM_STREAM_PLAYBACK; | ||
else | ||
stream_dir = SNDRV_PCM_STREAM_CAPTURE; | ||
|
||
/* disconnect FE from BE */ | ||
dpcm_be_disconnect(rtd, stream_dir); | ||
|
||
/* free pcm runtime */ | ||
kfree(rtd->dpcm[stream_dir].runtime); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Question: all these frees don't reflect what is done for the _new method, could we rely on a helper to avoid tracking all these actions? It looks like either copy-paste or something extracted from somewhere else. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is actually not a copy-paste at all. I traced all the steps from the point of adding the link to the time when the sound card is registered and freed all the data that is allocated. Here're the steps I traced:
So, in the vfe_free() method, I undid all of this. But I wonder if I can avoid all of this manually in the free method. Let me dig into these steps a bit more. |
||
|
||
pstr = &rtd->pcm->streams[stream_dir]; | ||
|
||
/* free pcm substream amd pcm */ | ||
kfree(pstr->substream); | ||
|
||
/* free pcm */ | ||
kfree(rtd->pcm); | ||
|
||
/* free codec dais and component list */ | ||
kfree(rtd->codec_dais); | ||
|
||
for_each_rtdcom_safe(rtd, rtdcom1, rtdcom2) | ||
kfree(rtdcom1); | ||
|
||
/* remove dai_link from card */ | ||
snd_soc_remove_dai_link(card, rtd->dai_link); | ||
|
||
/* free link */ | ||
kfree(rtd->dai_link); | ||
|
||
/* free runtime */ | ||
kfree(rtd); | ||
} | ||
} | ||
|
||
return 0; | ||
} | ||
EXPORT_SYMBOL_GPL(soc_dpcm_vfe_free); | ||
|
||
static int dpcm_fe_dai_open(struct snd_pcm_substream *fe_substream) | ||
{ | ||
struct snd_soc_pcm_runtime *fe = fe_substream->private_data; | ||
|
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 keep this line as is.