From: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
To: lgirdwood@gmail.com, broonie@kernel.org
Cc: alsa-devel@alsa-project.org, kai.vehmanen@linux.intel.com,
pierre-louis.bossart@linux.intel.com, rander.wang@intel.com,
ranjani.sridharan@linux.intel.com,
yung-chuan.liao@linux.intel.com
Subject: [PATCH 07/11] ASoC: SOF: topology: Extend the optionality of IPC ops to IPC as well
Date: Wed, 21 Dec 2022 12:23:24 +0200 [thread overview]
Message-ID: <20221221102328.9635-8-peter.ujfalusi@linux.intel.com> (raw)
In-Reply-To: <20221221102328.9635-1-peter.ujfalusi@linux.intel.com>
The IPC ops are optional, but they require that the ops struct is to be
allocated with all callbacks set to NULL.
Update the code to extend the optionality to:
sdev->ipc == NULL
sdev->ipc->ops == NULL
sdev->ipc->ops->[tplg] == NULL
sdev->ipc->ops->[tplg]->ops == NULL (treated optional currently)
At the same time standardize the naming of the ops pointer to tplg_ops
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
---
sound/soc/sof/topology.c | 91 ++++++++++++++++++++++++----------------
1 file changed, 55 insertions(+), 36 deletions(-)
diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c
index c668bd9d21ec..560771ba8fb9 100644
--- a/sound/soc/sof/topology.c
+++ b/sound/soc/sof/topology.c
@@ -54,11 +54,16 @@ int sof_update_ipc_object(struct snd_soc_component *scomp, void *object, enum so
size_t object_size, int token_instance_num)
{
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
- const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg;
- const struct sof_token_info *token_list = ipc_tplg_ops->token_list;
+ const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
+ const struct sof_token_info *token_list;
const struct sof_topology_token *tokens;
int i, j;
+ token_list = tplg_ops ? tplg_ops->token_list : NULL;
+ /* nothing to do if token_list is NULL */
+ if (!token_list)
+ return 0;
+
if (token_list[token_id].count < 0) {
dev_err(scomp->dev, "Invalid token count for token ID: %d\n", token_id);
return -EINVAL;
@@ -263,9 +268,9 @@ static int set_up_volume_table(struct snd_sof_control *scontrol,
{
struct snd_soc_component *scomp = scontrol->scomp;
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
- const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg;
+ const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
- if (tplg_ops->control->set_up_volume_table)
+ if (tplg_ops && tplg_ops->control && tplg_ops->control->set_up_volume_table)
return tplg_ops->control->set_up_volume_table(scontrol, tlv, size);
dev_err(scomp->dev, "Mandatory op %s not set\n", __func__);
@@ -490,13 +495,14 @@ static int sof_copy_tuples(struct snd_sof_dev *sdev, struct snd_soc_tplg_vendor_
int array_size, u32 token_id, int token_instance_num,
struct snd_sof_tuple *tuples, int tuples_size, int *num_copied_tuples)
{
- const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg;
- const struct sof_token_info *token_list = ipc_tplg_ops->token_list;
+ const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
+ const struct sof_token_info *token_list;
const struct sof_topology_token *tokens;
int found = 0;
int num_tokens, asize;
int i, j;
+ token_list = tplg_ops ? tplg_ops->token_list : NULL;
/* nothing to do if token_list is NULL */
if (!token_list)
return 0;
@@ -1015,14 +1021,14 @@ static int sof_control_unload(struct snd_soc_component *scomp,
struct snd_soc_dobj *dobj)
{
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
- const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg;
+ const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
struct snd_sof_control *scontrol = dobj->private;
int ret = 0;
dev_dbg(scomp->dev, "tplg: unload control name : %s\n", scontrol->name);
- if (ipc_tplg_ops->control_free) {
- ret = ipc_tplg_ops->control_free(sdev, scontrol);
+ if (tplg_ops && tplg_ops->control_free) {
+ ret = tplg_ops->control_free(sdev, scontrol);
if (ret < 0)
dev_err(scomp->dev, "failed to free control: %s\n", scontrol->name);
}
@@ -1201,12 +1207,17 @@ static int sof_widget_parse_tokens(struct snd_soc_component *scomp, struct snd_s
enum sof_tokens *object_token_list, int count)
{
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
- const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg;
- const struct sof_token_info *token_list = ipc_tplg_ops->token_list;
+ const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
struct snd_soc_tplg_private *private = &tw->priv;
+ const struct sof_token_info *token_list;
int num_tuples = 0;
int ret, i;
+ token_list = tplg_ops ? tplg_ops->token_list : NULL;
+ /* nothing to do if token_list is NULL */
+ if (!token_list)
+ return 0;
+
if (count > 0 && !object_token_list) {
dev_err(scomp->dev, "No token list for widget %s\n", swidget->widget->name);
return -EINVAL;
@@ -1375,13 +1386,13 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index,
struct snd_soc_tplg_dapm_widget *tw)
{
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
- const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg;
- const struct sof_ipc_tplg_widget_ops *widget_ops = ipc_tplg_ops->widget;
+ const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
+ const struct sof_ipc_tplg_widget_ops *widget_ops;
struct snd_soc_tplg_private *priv = &tw->priv;
+ enum sof_tokens *token_list = NULL;
struct snd_sof_widget *swidget;
struct snd_sof_dai *dai;
- enum sof_tokens *token_list;
- int token_list_size;
+ int token_list_size = 0;
int ret = 0;
swidget = kzalloc(sizeof(*swidget), GFP_KERNEL);
@@ -1440,8 +1451,11 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index,
swidget->num_sink_pins, swidget->num_source_pins,
strnlen(w->sname, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) > 0 ? w->sname : "none");
- token_list = widget_ops[w->id].token_list;
- token_list_size = widget_ops[w->id].token_list_size;
+ widget_ops = tplg_ops ? tplg_ops->widget : NULL;
+ if (widget_ops) {
+ token_list = widget_ops[w->id].token_list;
+ token_list_size = widget_ops[w->id].token_list_size;
+ }
/* handle any special case widgets */
switch (w->id) {
@@ -1525,7 +1539,7 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index,
/* bind widget to external event */
if (tw->event_type) {
- if (widget_ops[w->id].bind_event) {
+ if (widget_ops && widget_ops[w->id].bind_event) {
ret = widget_ops[w->id].bind_event(scomp, swidget,
le16_to_cpu(tw->event_type));
if (ret) {
@@ -1565,8 +1579,8 @@ static int sof_widget_unload(struct snd_soc_component *scomp,
struct snd_soc_dobj *dobj)
{
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
- const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg;
- const struct sof_ipc_tplg_widget_ops *widget_ops = ipc_tplg_ops->widget;
+ const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
+ const struct sof_ipc_tplg_widget_ops *widget_ops;
const struct snd_kcontrol_new *kc;
struct snd_soc_dapm_widget *widget;
struct snd_sof_control *scontrol;
@@ -1626,7 +1640,8 @@ static int sof_widget_unload(struct snd_soc_component *scomp,
out:
/* free IPC related data */
- if (widget_ops[swidget->id].ipc_free)
+ widget_ops = tplg_ops ? tplg_ops->widget : NULL;
+ if (widget_ops && widget_ops[swidget->id].ipc_free)
widget_ops[swidget->id].ipc_free(swidget);
ida_destroy(&swidget->src_queue_ida);
@@ -1784,9 +1799,9 @@ static int sof_link_load(struct snd_soc_component *scomp, int index, struct snd_
struct snd_soc_tplg_link_config *cfg)
{
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
- const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg;
- const struct sof_token_info *token_list = ipc_tplg_ops->token_list;
+ const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
struct snd_soc_tplg_private *private = &cfg->priv;
+ const struct sof_token_info *token_list;
struct snd_sof_dai_link *slink;
u32 token_id = 0;
int num_tuples = 0;
@@ -1856,6 +1871,7 @@ static int sof_link_load(struct snd_soc_component *scomp, int index, struct snd_
return ret;
}
+ token_list = tplg_ops ? tplg_ops->token_list : NULL;
if (!token_list)
goto out;
@@ -2100,16 +2116,18 @@ static int sof_set_pipe_widget(struct snd_sof_dev *sdev, struct snd_sof_widget *
static int sof_complete(struct snd_soc_component *scomp)
{
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
+ const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
struct snd_sof_widget *swidget, *comp_swidget;
- const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg;
- const struct sof_ipc_tplg_widget_ops *widget_ops = ipc_tplg_ops->widget;
+ const struct sof_ipc_tplg_widget_ops *widget_ops;
struct snd_sof_control *scontrol;
int ret;
+ widget_ops = tplg_ops ? tplg_ops->widget : NULL;
+
/* first update all control IPC structures based on the IPC version */
- if (ipc_tplg_ops->control_setup)
+ if (tplg_ops && tplg_ops->control_setup)
list_for_each_entry(scontrol, &sdev->kcontrol_list, list) {
- ret = ipc_tplg_ops->control_setup(sdev, scontrol);
+ ret = tplg_ops->control_setup(sdev, scontrol);
if (ret < 0) {
dev_err(sdev->dev, "failed updating IPC struct for control %s\n",
scontrol->name);
@@ -2123,7 +2141,7 @@ static int sof_complete(struct snd_soc_component *scomp)
* associated memories.
*/
list_for_each_entry(swidget, &sdev->widget_list, list) {
- if (widget_ops[swidget->id].ipc_setup) {
+ if (widget_ops && widget_ops[swidget->id].ipc_setup) {
ret = widget_ops[swidget->id].ipc_setup(swidget);
if (ret < 0) {
dev_err(sdev->dev, "failed updating IPC struct for %s\n",
@@ -2155,15 +2173,16 @@ static int sof_complete(struct snd_soc_component *scomp)
/* verify topology components loading including dynamic pipelines */
if (sof_debug_check_flag(SOF_DBG_VERIFY_TPLG)) {
- if (ipc_tplg_ops->set_up_all_pipelines && ipc_tplg_ops->tear_down_all_pipelines) {
- ret = ipc_tplg_ops->set_up_all_pipelines(sdev, true);
+ if (tplg_ops && tplg_ops->set_up_all_pipelines &&
+ tplg_ops->tear_down_all_pipelines) {
+ ret = tplg_ops->set_up_all_pipelines(sdev, true);
if (ret < 0) {
dev_err(sdev->dev, "Failed to set up all topology pipelines: %d\n",
ret);
return ret;
}
- ret = ipc_tplg_ops->tear_down_all_pipelines(sdev, true);
+ ret = tplg_ops->tear_down_all_pipelines(sdev, true);
if (ret < 0) {
dev_err(sdev->dev, "Failed to tear down topology pipelines: %d\n",
ret);
@@ -2173,8 +2192,8 @@ static int sof_complete(struct snd_soc_component *scomp)
}
/* set up static pipelines */
- if (ipc_tplg_ops->set_up_all_pipelines)
- return ipc_tplg_ops->set_up_all_pipelines(sdev, false);
+ if (tplg_ops && tplg_ops->set_up_all_pipelines)
+ return tplg_ops->set_up_all_pipelines(sdev, false);
return 0;
}
@@ -2184,10 +2203,10 @@ static int sof_manifest(struct snd_soc_component *scomp, int index,
struct snd_soc_tplg_manifest *man)
{
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
- const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg;
+ const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
- if (ipc_tplg_ops->parse_manifest)
- return ipc_tplg_ops->parse_manifest(scomp, index, man);
+ if (tplg_ops && tplg_ops->parse_manifest)
+ return tplg_ops->parse_manifest(scomp, index, man);
return 0;
}
--
2.39.0
next prev parent reply other threads:[~2022-12-21 10:26 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-12-21 10:23 [PATCH 00/11] ASoC: SOF: Extend the IPC ops optionality Peter Ujfalusi
2022-12-21 10:23 ` [PATCH 01/11] ASoC: SOF: sof-audio: Treat tplg_ops->route_setup() as optional Peter Ujfalusi
2022-12-21 10:23 ` [PATCH 02/11] ASoC: SOF: sof-audio: Update documentation for sof_ipc_tplg_ops Peter Ujfalusi
2022-12-21 10:23 ` [PATCH 03/11] ASoC: SOF: Add helper macro to be used to get an IPC ops Peter Ujfalusi
2022-12-21 10:23 ` [PATCH 04/11] ASoC: SOF: pcm: Extend the optionality of IPC ops to IPC as well Peter Ujfalusi
2022-12-21 10:23 ` [PATCH 05/11] ASoC: SOF: control: " Peter Ujfalusi
2022-12-21 10:23 ` [PATCH 06/11] ASoC: SOF: sof-audio: " Peter Ujfalusi
2022-12-21 10:23 ` Peter Ujfalusi [this message]
2022-12-21 10:23 ` [PATCH 08/11] ASoC: SOF: pm: " Peter Ujfalusi
2022-12-21 10:23 ` [PATCH 09/11] ASoC: SOF: sof-priv: Mark fw_tracing ops optional in documentation Peter Ujfalusi
2022-12-21 10:23 ` [PATCH 10/11] ASoC: SOF: trace: Use sof_ipc_get_ops() in sof_fw_trace_init Peter Ujfalusi
2022-12-21 10:23 ` [PATCH 11/11] ASoC: SOF: trace: No need to check for op pointer in sof_fw_trace_free() Peter Ujfalusi
2022-12-27 11:57 ` [PATCH 00/11] ASoC: SOF: Extend the IPC ops optionality Mark Brown
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20221221102328.9635-8-peter.ujfalusi@linux.intel.com \
--to=peter.ujfalusi@linux.intel.com \
--cc=alsa-devel@alsa-project.org \
--cc=broonie@kernel.org \
--cc=kai.vehmanen@linux.intel.com \
--cc=lgirdwood@gmail.com \
--cc=pierre-louis.bossart@linux.intel.com \
--cc=rander.wang@intel.com \
--cc=ranjani.sridharan@linux.intel.com \
--cc=yung-chuan.liao@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox