diff --git a/include/sound/sof/topology.h b/include/sound/sof/topology.h index f56e80d09b3207..49adac1c5e7352 100644 --- a/include/sound/sof/topology.h +++ b/include/sound/sof/topology.h @@ -57,8 +57,8 @@ struct sof_ipc_comp { uint32_t pipeline_id; uint32_t core; - /* reserved for future use */ - uint32_t reserved[1]; + /* extended data offset, 0 if no extended data */ + uint32_t ext_data_offset; } __packed; /* @@ -300,4 +300,9 @@ enum sof_event_types { SOF_KEYWORD_DETECT_DAPM_EVENT, }; +/* extended data struct for component new */ +struct sof_ipc_comp_new_ext { + uint8_t uuid[16]; +} __packed; + #endif diff --git a/include/uapi/sound/sof/tokens.h b/include/uapi/sound/sof/tokens.h index 37f5aaa09c2b66..d3aae4ad89590f 100644 --- a/include/uapi/sound/sof/tokens.h +++ b/include/uapi/sound/sof/tokens.h @@ -74,6 +74,7 @@ * #define SOF_TKN_COMP_PRELOAD_COUNT 403 */ #define SOF_TKN_COMP_CORE_ID 404 +#define SOF_TKN_COMP_UUID 405 /* SSP */ #define SOF_TKN_INTEL_SSP_CLKS_CONTROL 500 diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c index 824f0103eadfc5..e1f22e50ca28d7 100644 --- a/sound/soc/sof/sof-audio.c +++ b/sound/soc/sof/sof-audio.c @@ -165,8 +165,9 @@ int sof_restore_pipelines(struct device *dev) struct snd_sof_route *sroute; struct sof_ipc_pipe_new *pipeline; struct snd_sof_dai *dai; - struct sof_ipc_comp_dai *comp_dai; struct sof_ipc_cmd_hdr *hdr; + struct sof_ipc_comp *comp; + size_t ipc_size; int ret; /* restore pipeline components */ @@ -189,12 +190,25 @@ int sof_restore_pipelines(struct device *dev) switch (swidget->id) { case snd_soc_dapm_dai_in: case snd_soc_dapm_dai_out: + ipc_size = sizeof(struct sof_ipc_comp_dai) + + sizeof(struct sof_ipc_comp_new_ext); + comp = kzalloc(ipc_size, GFP_KERNEL); + if (!comp) + return -ENOMEM; + dai = swidget->private; - comp_dai = &dai->comp_dai; - ret = sof_ipc_tx_message(sdev->ipc, - comp_dai->comp.hdr.cmd, - comp_dai, sizeof(*comp_dai), + /* restore the struct sof_ipc_comp_dai */ + memcpy(comp, &dai->comp_dai, + sizeof(struct sof_ipc_comp_dai)); + + /* append extended data to the end of the component */ + memcpy((u8 *)comp + sizeof(struct sof_ipc_comp_dai), + &swidget->comp_ext, sizeof(swidget->comp_ext)); + + ret = sof_ipc_tx_message(sdev->ipc, comp->hdr.cmd, + comp, ipc_size, &r, sizeof(r)); + kfree(comp); break; case snd_soc_dapm_scheduler: diff --git a/sound/soc/sof/sof-audio.h b/sound/soc/sof/sof-audio.h index 7f8be8817e69ea..60c1a47b396ba5 100644 --- a/sound/soc/sof/sof-audio.h +++ b/sound/soc/sof/sof-audio.h @@ -89,6 +89,9 @@ struct snd_sof_widget { struct snd_soc_dapm_widget *widget; struct list_head list; /* list in sdev widget list */ + /* extended data for component new */ + struct sof_ipc_comp_new_ext comp_ext; + void *private; /* core does not touch this */ }; diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index 34f2dace020f82..26e297f8cc41be 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -492,6 +492,16 @@ static int get_token_u16(void *elem, void *object, u32 offset, u32 size) return 0; } +static int get_token_uuid(void *elem, void *object, u32 offset, u32 size) +{ + struct snd_soc_tplg_vendor_uuid_elem *velem = elem; + u8 *dst = (u8 *)object + offset; + + memcpy(dst, velem->uuid, UUID_SIZE); + + return 0; +} + static int get_token_comp_format(void *elem, void *object, u32 offset, u32 size) { struct snd_soc_tplg_vendor_string_elem *velem = elem; @@ -725,6 +735,13 @@ static const struct sof_topology_token core_tokens[] = { offsetof(struct sof_ipc_comp, core), 0}, }; +/* Component extended tokens */ +static const struct sof_topology_token comp_ext_tokens[] = { + {SOF_TKN_COMP_UUID, + SND_SOC_TPLG_TUPLE_TYPE_UUID, get_token_uuid, + offsetof(struct sof_ipc_comp_new_ext, uuid), 0}, +}; + /* * DMIC PDM Tokens * SOF_TKN_INTEL_DMIC_PDM_CTRL_ID should be the first token @@ -1436,49 +1453,60 @@ static int sof_widget_load_dai(struct snd_soc_component *scomp, int index, { struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); struct snd_soc_tplg_private *private = &tw->priv; - struct sof_ipc_comp_dai comp_dai; + struct sof_ipc_comp_dai *comp_dai; + size_t ipc_size = sizeof(*comp_dai) + sizeof(swidget->comp_ext); int ret; + comp_dai = kzalloc(ipc_size, GFP_KERNEL); + if (!comp_dai) + return -ENOMEM; + /* configure dai IPC message */ - memset(&comp_dai, 0, sizeof(comp_dai)); - comp_dai.comp.hdr.size = sizeof(comp_dai); - comp_dai.comp.hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_COMP_NEW; - comp_dai.comp.id = swidget->comp_id; - comp_dai.comp.type = SOF_COMP_DAI; - comp_dai.comp.pipeline_id = index; - comp_dai.comp.core = core; - comp_dai.config.hdr.size = sizeof(comp_dai.config); - - ret = sof_parse_tokens(scomp, &comp_dai, dai_tokens, + comp_dai->comp.hdr.size = ipc_size; + comp_dai->comp.hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_COMP_NEW; + comp_dai->comp.id = swidget->comp_id; + comp_dai->comp.type = SOF_COMP_DAI; + comp_dai->comp.pipeline_id = index; + comp_dai->comp.core = core; + comp_dai->config.hdr.size = sizeof(comp_dai->config); + + /* append extended data to the end of the component */ + memcpy((u8 *)comp_dai + sizeof(*comp_dai), + &swidget->comp_ext, sizeof(swidget->comp_ext)); + comp_dai->comp.ext_data_offset = sizeof(*comp_dai); + + ret = sof_parse_tokens(scomp, comp_dai, dai_tokens, ARRAY_SIZE(dai_tokens), private->array, le32_to_cpu(private->size)); if (ret != 0) { dev_err(scomp->dev, "error: parse dai tokens failed %d\n", le32_to_cpu(private->size)); - return ret; + goto finish; } - ret = sof_parse_tokens(scomp, &comp_dai.config, comp_tokens, + ret = sof_parse_tokens(scomp, &comp_dai->config, comp_tokens, ARRAY_SIZE(comp_tokens), private->array, le32_to_cpu(private->size)); if (ret != 0) { dev_err(scomp->dev, "error: parse dai.cfg tokens failed %d\n", private->size); - return ret; + goto finish; } dev_dbg(scomp->dev, "dai %s: type %d index %d\n", - swidget->widget->name, comp_dai.type, comp_dai.dai_index); - sof_dbg_comp_config(scomp, &comp_dai.config); + swidget->widget->name, comp_dai->type, comp_dai->dai_index); + sof_dbg_comp_config(scomp, &comp_dai->config); - ret = sof_ipc_tx_message(sdev->ipc, comp_dai.comp.hdr.cmd, - &comp_dai, sizeof(comp_dai), r, sizeof(*r)); + ret = sof_ipc_tx_message(sdev->ipc, comp_dai->comp.hdr.cmd, + comp_dai, ipc_size, r, sizeof(*r)); if (ret == 0 && dai) { dai->scomp = scomp; - memcpy(&dai->comp_dai, &comp_dai, sizeof(comp_dai)); + memcpy(&dai->comp_dai, comp_dai, sizeof(*comp_dai)); } +finish: + kfree(comp_dai); return ret; } @@ -1494,20 +1522,26 @@ static int sof_widget_load_buffer(struct snd_soc_component *scomp, int index, struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); struct snd_soc_tplg_private *private = &tw->priv; struct sof_ipc_buffer *buffer; + size_t ipc_size = sizeof(*buffer) + sizeof(swidget->comp_ext); int ret; - buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); + buffer = kzalloc(ipc_size, GFP_KERNEL); if (!buffer) return -ENOMEM; /* configure dai IPC message */ - buffer->comp.hdr.size = sizeof(*buffer); + buffer->comp.hdr.size = ipc_size; buffer->comp.hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_BUFFER_NEW; buffer->comp.id = swidget->comp_id; buffer->comp.type = SOF_COMP_BUFFER; buffer->comp.pipeline_id = index; buffer->comp.core = core; + /* append extended data to the end of the buffer */ + memcpy((u8 *)buffer + sizeof(*buffer), + &swidget->comp_ext, sizeof(swidget->comp_ext)); + buffer->comp.ext_data_offset = sizeof(*buffer); + ret = sof_parse_tokens(scomp, buffer, buffer_tokens, ARRAY_SIZE(buffer_tokens), private->array, le32_to_cpu(private->size)); @@ -1524,7 +1558,7 @@ static int sof_widget_load_buffer(struct snd_soc_component *scomp, int index, swidget->private = buffer; ret = sof_ipc_tx_message(sdev->ipc, buffer->comp.hdr.cmd, buffer, - sizeof(*buffer), r, sizeof(*r)); + ipc_size, r, sizeof(*r)); if (ret < 0) { dev_err(scomp->dev, "error: buffer %s load failed\n", swidget->widget->name); @@ -1566,14 +1600,15 @@ static int sof_widget_load_pcm(struct snd_soc_component *scomp, int index, struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); struct snd_soc_tplg_private *private = &tw->priv; struct sof_ipc_comp_host *host; + size_t ipc_size = sizeof(*host) + sizeof(swidget->comp_ext); int ret; - host = kzalloc(sizeof(*host), GFP_KERNEL); + host = kzalloc(ipc_size, GFP_KERNEL); if (!host) return -ENOMEM; /* configure host comp IPC message */ - host->comp.hdr.size = sizeof(*host); + host->comp.hdr.size = ipc_size; host->comp.hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_COMP_NEW; host->comp.id = swidget->comp_id; host->comp.type = SOF_COMP_HOST; @@ -1582,6 +1617,11 @@ static int sof_widget_load_pcm(struct snd_soc_component *scomp, int index, host->direction = dir; host->config.hdr.size = sizeof(host->config); + /* append extended data to the end of the component */ + memcpy((u8 *)host + sizeof(*host), + &swidget->comp_ext, sizeof(swidget->comp_ext)); + host->comp.ext_data_offset = sizeof(*host); + ret = sof_parse_tokens(scomp, host, pcm_tokens, ARRAY_SIZE(pcm_tokens), private->array, le32_to_cpu(private->size)); @@ -1606,7 +1646,7 @@ static int sof_widget_load_pcm(struct snd_soc_component *scomp, int index, swidget->private = host; ret = sof_ipc_tx_message(sdev->ipc, host->comp.hdr.cmd, host, - sizeof(*host), r, sizeof(*r)); + ipc_size, r, sizeof(*r)); if (ret >= 0) return ret; err: @@ -1705,14 +1745,15 @@ static int sof_widget_load_mixer(struct snd_soc_component *scomp, int index, struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); struct snd_soc_tplg_private *private = &tw->priv; struct sof_ipc_comp_mixer *mixer; + size_t ipc_size = sizeof(*mixer) + sizeof(swidget->comp_ext); int ret; - mixer = kzalloc(sizeof(*mixer), GFP_KERNEL); + mixer = kzalloc(ipc_size, GFP_KERNEL); if (!mixer) return -ENOMEM; /* configure mixer IPC message */ - mixer->comp.hdr.size = sizeof(*mixer); + mixer->comp.hdr.size = ipc_size; mixer->comp.hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_COMP_NEW; mixer->comp.id = swidget->comp_id; mixer->comp.type = SOF_COMP_MIXER; @@ -1720,6 +1761,11 @@ static int sof_widget_load_mixer(struct snd_soc_component *scomp, int index, mixer->comp.core = core; mixer->config.hdr.size = sizeof(mixer->config); + /* append extended data to the end of the component */ + memcpy((u8 *)mixer + sizeof(*mixer), + &swidget->comp_ext, sizeof(swidget->comp_ext)); + mixer->comp.ext_data_offset = sizeof(*mixer); + ret = sof_parse_tokens(scomp, &mixer->config, comp_tokens, ARRAY_SIZE(comp_tokens), private->array, le32_to_cpu(private->size)); @@ -1735,7 +1781,7 @@ static int sof_widget_load_mixer(struct snd_soc_component *scomp, int index, swidget->private = mixer; ret = sof_ipc_tx_message(sdev->ipc, mixer->comp.hdr.cmd, mixer, - sizeof(*mixer), r, sizeof(*r)); + ipc_size, r, sizeof(*r)); if (ret < 0) kfree(mixer); @@ -1753,14 +1799,15 @@ static int sof_widget_load_mux(struct snd_soc_component *scomp, int index, struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); struct snd_soc_tplg_private *private = &tw->priv; struct sof_ipc_comp_mux *mux; + size_t ipc_size = sizeof(*mux) + sizeof(swidget->comp_ext); int ret; - mux = kzalloc(sizeof(*mux), GFP_KERNEL); + mux = kzalloc(ipc_size, GFP_KERNEL); if (!mux) return -ENOMEM; /* configure mux IPC message */ - mux->comp.hdr.size = sizeof(*mux); + mux->comp.hdr.size = ipc_size; mux->comp.hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_COMP_NEW; mux->comp.id = swidget->comp_id; mux->comp.type = SOF_COMP_MUX; @@ -1768,6 +1815,11 @@ static int sof_widget_load_mux(struct snd_soc_component *scomp, int index, mux->comp.core = core; mux->config.hdr.size = sizeof(mux->config); + /* append extended data to the end of the component */ + memcpy((u8 *)mux + sizeof(*mux), + &swidget->comp_ext, sizeof(swidget->comp_ext)); + mux->comp.ext_data_offset = sizeof(*mux); + ret = sof_parse_tokens(scomp, &mux->config, comp_tokens, ARRAY_SIZE(comp_tokens), private->array, le32_to_cpu(private->size)); @@ -1783,7 +1835,7 @@ static int sof_widget_load_mux(struct snd_soc_component *scomp, int index, swidget->private = mux; ret = sof_ipc_tx_message(sdev->ipc, mux->comp.hdr.cmd, mux, - sizeof(*mux), r, sizeof(*r)); + ipc_size, r, sizeof(*r)); if (ret < 0) kfree(mux); @@ -1803,11 +1855,12 @@ static int sof_widget_load_pga(struct snd_soc_component *scomp, int index, struct snd_soc_tplg_private *private = &tw->priv; struct sof_ipc_comp_volume *volume; struct snd_sof_control *scontrol; + size_t ipc_size = sizeof(*volume) + sizeof(swidget->comp_ext); int min_step; int max_step; int ret; - volume = kzalloc(sizeof(*volume), GFP_KERNEL); + volume = kzalloc(ipc_size, GFP_KERNEL); if (!volume) return -ENOMEM; @@ -1819,7 +1872,7 @@ static int sof_widget_load_pga(struct snd_soc_component *scomp, int index, } /* configure volume IPC message */ - volume->comp.hdr.size = sizeof(*volume); + volume->comp.hdr.size = ipc_size; volume->comp.hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_COMP_NEW; volume->comp.id = swidget->comp_id; volume->comp.type = SOF_COMP_VOLUME; @@ -1827,6 +1880,11 @@ static int sof_widget_load_pga(struct snd_soc_component *scomp, int index, volume->comp.core = core; volume->config.hdr.size = sizeof(volume->config); + /* append extended data to the end of the component */ + memcpy((u8 *)volume + sizeof(*volume), + &swidget->comp_ext, sizeof(swidget->comp_ext)); + volume->comp.ext_data_offset = sizeof(*volume); + ret = sof_parse_tokens(scomp, volume, volume_tokens, ARRAY_SIZE(volume_tokens), private->array, le32_to_cpu(private->size)); @@ -1861,7 +1919,7 @@ static int sof_widget_load_pga(struct snd_soc_component *scomp, int index, } ret = sof_ipc_tx_message(sdev->ipc, volume->comp.hdr.cmd, volume, - sizeof(*volume), r, sizeof(*r)); + ipc_size, r, sizeof(*r)); if (ret >= 0) return ret; err: @@ -1881,14 +1939,15 @@ static int sof_widget_load_src(struct snd_soc_component *scomp, int index, struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); struct snd_soc_tplg_private *private = &tw->priv; struct sof_ipc_comp_src *src; + size_t ipc_size = sizeof(*src) + sizeof(swidget->comp_ext); int ret; - src = kzalloc(sizeof(*src), GFP_KERNEL); + src = kzalloc(ipc_size, GFP_KERNEL); if (!src) return -ENOMEM; /* configure src IPC message */ - src->comp.hdr.size = sizeof(*src); + src->comp.hdr.size = ipc_size; src->comp.hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_COMP_NEW; src->comp.id = swidget->comp_id; src->comp.type = SOF_COMP_SRC; @@ -1896,6 +1955,11 @@ static int sof_widget_load_src(struct snd_soc_component *scomp, int index, src->comp.core = core; src->config.hdr.size = sizeof(src->config); + /* append extended data to the end of the component */ + memcpy((u8 *)src + sizeof(*src), + &swidget->comp_ext, sizeof(swidget->comp_ext)); + src->comp.ext_data_offset = sizeof(*src); + ret = sof_parse_tokens(scomp, src, src_tokens, ARRAY_SIZE(src_tokens), private->array, le32_to_cpu(private->size)); @@ -1921,7 +1985,7 @@ static int sof_widget_load_src(struct snd_soc_component *scomp, int index, swidget->private = src; ret = sof_ipc_tx_message(sdev->ipc, src->comp.hdr.cmd, src, - sizeof(*src), r, sizeof(*r)); + ipc_size, r, sizeof(*r)); if (ret >= 0) return ret; err: @@ -1941,14 +2005,15 @@ static int sof_widget_load_asrc(struct snd_soc_component *scomp, int index, struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); struct snd_soc_tplg_private *private = &tw->priv; struct sof_ipc_comp_asrc *asrc; + size_t ipc_size = sizeof(*asrc) + sizeof(swidget->comp_ext); int ret; - asrc = kzalloc(sizeof(*asrc), GFP_KERNEL); + asrc = kzalloc(ipc_size, GFP_KERNEL); if (!asrc) return -ENOMEM; /* configure ASRC IPC message */ - asrc->comp.hdr.size = sizeof(*asrc); + asrc->comp.hdr.size = ipc_size; asrc->comp.hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_COMP_NEW; asrc->comp.id = swidget->comp_id; asrc->comp.type = SOF_COMP_ASRC; @@ -1956,6 +2021,11 @@ static int sof_widget_load_asrc(struct snd_soc_component *scomp, int index, asrc->comp.core = core; asrc->config.hdr.size = sizeof(asrc->config); + /* append extended to the end of the component */ + memcpy((u8 *)asrc + sizeof(*asrc), + &swidget->comp_ext, sizeof(swidget->comp_ext)); + asrc->comp.ext_data_offset = sizeof(*asrc); + ret = sof_parse_tokens(scomp, asrc, asrc_tokens, ARRAY_SIZE(asrc_tokens), private->array, le32_to_cpu(private->size)); @@ -1983,7 +2053,7 @@ static int sof_widget_load_asrc(struct snd_soc_component *scomp, int index, swidget->private = asrc; ret = sof_ipc_tx_message(sdev->ipc, asrc->comp.hdr.cmd, asrc, - sizeof(*asrc), r, sizeof(*r)); + ipc_size, r, sizeof(*r)); if (ret >= 0) return ret; err: @@ -2003,14 +2073,15 @@ static int sof_widget_load_siggen(struct snd_soc_component *scomp, int index, struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); struct snd_soc_tplg_private *private = &tw->priv; struct sof_ipc_comp_tone *tone; + size_t ipc_size = sizeof(*tone) + sizeof(swidget->comp_ext); int ret; - tone = kzalloc(sizeof(*tone), GFP_KERNEL); + tone = kzalloc(ipc_size, GFP_KERNEL); if (!tone) return -ENOMEM; /* configure siggen IPC message */ - tone->comp.hdr.size = sizeof(*tone); + tone->comp.hdr.size = ipc_size; tone->comp.hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_COMP_NEW; tone->comp.id = swidget->comp_id; tone->comp.type = SOF_COMP_TONE; @@ -2018,6 +2089,11 @@ static int sof_widget_load_siggen(struct snd_soc_component *scomp, int index, tone->comp.core = core; tone->config.hdr.size = sizeof(tone->config); + /* append extended data to the end of the component */ + memcpy((u8 *)tone + sizeof(*tone), + &swidget->comp_ext, sizeof(swidget->comp_ext)); + tone->comp.ext_data_offset = sizeof(*tone); + ret = sof_parse_tokens(scomp, tone, tone_tokens, ARRAY_SIZE(tone_tokens), private->array, le32_to_cpu(private->size)); @@ -2043,7 +2119,7 @@ static int sof_widget_load_siggen(struct snd_soc_component *scomp, int index, swidget->private = tone; ret = sof_ipc_tx_message(sdev->ipc, tone->comp.hdr.cmd, tone, - sizeof(*tone), r, sizeof(*r)); + ipc_size, r, sizeof(*r)); if (ret >= 0) return ret; err: @@ -2164,8 +2240,7 @@ static int sof_process_load(struct snd_soc_component *scomp, int index, } ipc_size = sizeof(struct sof_ipc_comp_process) + - le32_to_cpu(private->size) + - ipc_data_size; + ipc_data_size + sizeof(swidget->comp_ext); /* we are exceeding max ipc size, config needs to be sent separately */ if (ipc_size > SOF_IPC_MSG_MAX_SIZE) { @@ -2187,6 +2262,11 @@ static int sof_process_load(struct snd_soc_component *scomp, int index, process->comp.pipeline_id = index; process->config.hdr.size = sizeof(process->config); + /* append extended data to the end of the component */ + memcpy((u8 *)process + sizeof(*process) + ipc_data_size, + &swidget->comp_ext, sizeof(swidget->comp_ext)); + process->comp.ext_data_offset = sizeof(*process) + ipc_data_size; + ret = sof_parse_tokens(scomp, &process->config, comp_tokens, ARRAY_SIZE(comp_tokens), private->array, le32_to_cpu(private->size)); @@ -2378,6 +2458,16 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index, return ret; } + ret = sof_parse_tokens(scomp, &swidget->comp_ext, comp_ext_tokens, + ARRAY_SIZE(comp_ext_tokens), tw->priv.array, + le32_to_cpu(tw->priv.size)); + if (ret != 0) { + dev_err(scomp->dev, "error: parsing comp_ext_tokens failed %d\n", + ret); + kfree(swidget); + return ret; + } + /* handle any special case widgets */ switch (w->id) { case snd_soc_dapm_dai_in: