From a4ad42d28618eef83bee02e0a19af0d467bd9722 Mon Sep 17 00:00:00 2001 From: Kareem Shaik Date: Wed, 18 Aug 2021 09:57:39 +0200 Subject: ASoC: Intel: Skylake: Support multiple format configs A module can have two kinds of set params, as per topology requirements. For example, one pre-init and one post-init. But currently, there is support for just one type, as the format_config. This patch extends the format_configs to 4, so as to be able to support pre-init, post-init and post-bind type of set params, for the same module, simultaneously. Signed-off-by: Kareem Shaik Signed-off-by: Gustaw Lewandowski Signed-off-by: Cezary Rojewski Tested-by: Lukasz Majczak Link: https://lore.kernel.org/r/20210818075742.1515155-9-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/skylake/skl-topology.c | 99 ++++++++++++++++++++++------------ 1 file changed, 64 insertions(+), 35 deletions(-) (limited to 'sound/soc/intel/skylake/skl-topology.c') diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index 51fb594bb172..04fbf83f3835 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -292,7 +292,7 @@ static int skl_tplg_update_be_blob(struct snd_soc_dapm_widget *w, struct skl_module_iface *m_iface = &m_cfg->module->formats[fmt_idx]; /* check if we already have blob */ - if (m_cfg->formats_config.caps_size > 0) + if (m_cfg->formats_config[SKL_PARAM_INIT].caps_size > 0) return 0; dev_dbg(skl->dev, "Applying default cfg blob\n"); @@ -328,8 +328,8 @@ static int skl_tplg_update_be_blob(struct snd_soc_dapm_widget *w, cfg = skl_get_ep_blob(skl, m_cfg->vbus_id, link_type, s_fmt, ch, s_freq, dir, dev_type); if (cfg) { - m_cfg->formats_config.caps_size = cfg->size; - m_cfg->formats_config.caps = (u32 *) &cfg->caps; + m_cfg->formats_config[SKL_PARAM_INIT].caps_size = cfg->size; + m_cfg->formats_config[SKL_PARAM_INIT].caps = (u32 *)&cfg->caps; } else { dev_err(skl->dev, "Blob NULL for id %x type %d dirn %d\n", m_cfg->vbus_id, link_type, dir); @@ -386,9 +386,9 @@ static int skl_tplg_set_module_params(struct snd_soc_dapm_widget *w, struct skl_algo_data *bc; struct skl_specific_cfg *sp_cfg; - if (mconfig->formats_config.caps_size > 0 && - mconfig->formats_config.set_params == SKL_PARAM_SET) { - sp_cfg = &mconfig->formats_config; + if (mconfig->formats_config[SKL_PARAM_SET].caps_size > 0 && + mconfig->formats_config[SKL_PARAM_SET].set_params == SKL_PARAM_SET) { + sp_cfg = &mconfig->formats_config[SKL_PARAM_SET]; ret = skl_set_module_params(skl, sp_cfg->caps, sp_cfg->caps_size, sp_cfg->param_id, mconfig); @@ -438,8 +438,10 @@ static int skl_tplg_set_module_init_data(struct snd_soc_dapm_widget *w) if (bc->set_params != SKL_PARAM_INIT) continue; - mconfig->formats_config.caps = (u32 *)bc->params; - mconfig->formats_config.caps_size = bc->size; + mconfig->formats_config[SKL_PARAM_INIT].caps = + (u32 *)bc->params; + mconfig->formats_config[SKL_PARAM_INIT].caps_size = + bc->size; break; } @@ -798,9 +800,10 @@ static int skl_tplg_set_module_bind_params(struct snd_soc_dapm_widget *w, return 0; } - if (mconfig->formats_config.caps_size > 0 && - mconfig->formats_config.set_params == SKL_PARAM_BIND) { - sp_cfg = &mconfig->formats_config; + if (mconfig->formats_config[SKL_PARAM_BIND].caps_size > 0 && + mconfig->formats_config[SKL_PARAM_BIND].set_params == + SKL_PARAM_BIND) { + sp_cfg = &mconfig->formats_config[SKL_PARAM_BIND]; ret = skl_set_module_params(skl, sp_cfg->caps, sp_cfg->caps_size, sp_cfg->param_id, mconfig); @@ -1496,7 +1499,8 @@ static int skl_tplg_mic_control_get(struct snd_kcontrol *kcontrol, static int skl_fill_mic_sel_params(struct skl_module_cfg *mconfig, struct skl_mic_sel_config *mic_cfg, struct device *dev) { - struct skl_specific_cfg *sp_cfg = &mconfig->formats_config; + struct skl_specific_cfg *sp_cfg = + &mconfig->formats_config[SKL_PARAM_INIT]; sp_cfg->caps_size = sizeof(struct skl_mic_sel_config); sp_cfg->set_params = SKL_PARAM_SET; @@ -1849,8 +1853,8 @@ static int skl_tplg_be_fill_pipe_params(struct snd_soc_dai *dai, pipe_fmt->freq, pipe->direction, dev_type); if (cfg) { - mconfig->formats_config.caps_size = cfg->size; - mconfig->formats_config.caps = (u32 *) &cfg->caps; + mconfig->formats_config[SKL_PARAM_INIT].caps_size = cfg->size; + mconfig->formats_config[SKL_PARAM_INIT].caps = (u32 *)&cfg->caps; } else { dev_err(dai->dev, "Blob NULL for id:%d type:%d dirn:%d ch:%d, freq:%d, fmt:%d\n", mconfig->vbus_id, link_type, params->stream, @@ -2567,19 +2571,26 @@ static int skl_tplg_get_token(struct device *dev, break; + case SKL_TKN_U32_FMT_CFG_IDX: + if (tkn_elem->value > SKL_MAX_PARAMS_TYPES) + return -EINVAL; + + mconfig->fmt_cfg_idx = tkn_elem->value; + break; + case SKL_TKN_U32_CAPS_SIZE: - mconfig->formats_config.caps_size = + mconfig->formats_config[mconfig->fmt_cfg_idx].caps_size = tkn_elem->value; break; case SKL_TKN_U32_CAPS_SET_PARAMS: - mconfig->formats_config.set_params = + mconfig->formats_config[mconfig->fmt_cfg_idx].set_params = tkn_elem->value; break; case SKL_TKN_U32_CAPS_PARAMS_ID: - mconfig->formats_config.param_id = + mconfig->formats_config[mconfig->fmt_cfg_idx].param_id = tkn_elem->value; break; @@ -2793,6 +2804,7 @@ static int skl_tplg_get_pvt_data_v4(struct snd_soc_tplg_dapm_widget *tplg_w, struct skl_dfw_v4_module *dfw = (struct skl_dfw_v4_module *)tplg_w->priv.data; int ret; + int idx = mconfig->fmt_cfg_idx; dev_dbg(dev, "Parsing Skylake v4 widget topology data\n"); @@ -2826,7 +2838,7 @@ static int skl_tplg_get_pvt_data_v4(struct snd_soc_tplg_dapm_widget *tplg_w, mconfig->dev_type = dfw->dev_type; mconfig->hw_conn_type = dfw->hw_conn_type; mconfig->time_slot = dfw->time_slot; - mconfig->formats_config.caps_size = dfw->caps.caps_size; + mconfig->formats_config[idx].caps_size = dfw->caps.caps_size; mconfig->m_in_pin = devm_kcalloc(dev, MAX_IN_QUEUE, sizeof(*mconfig->m_in_pin), @@ -2847,21 +2859,39 @@ static int skl_tplg_get_pvt_data_v4(struct snd_soc_tplg_dapm_widget *tplg_w, dfw->is_dynamic_out_pin, mconfig->module->max_output_pins); - if (mconfig->formats_config.caps_size) { - mconfig->formats_config.set_params = dfw->caps.set_params; - mconfig->formats_config.param_id = dfw->caps.param_id; - mconfig->formats_config.caps = - devm_kzalloc(dev, mconfig->formats_config.caps_size, + if (mconfig->formats_config[idx].caps_size) { + mconfig->formats_config[idx].set_params = dfw->caps.set_params; + mconfig->formats_config[idx].param_id = dfw->caps.param_id; + mconfig->formats_config[idx].caps = + devm_kzalloc(dev, mconfig->formats_config[idx].caps_size, GFP_KERNEL); - if (!mconfig->formats_config.caps) + if (!mconfig->formats_config[idx].caps) return -ENOMEM; - memcpy(mconfig->formats_config.caps, dfw->caps.caps, + memcpy(mconfig->formats_config[idx].caps, dfw->caps.caps, dfw->caps.caps_size); } return 0; } +static int skl_tplg_get_caps_data(struct device *dev, char *data, + struct skl_module_cfg *mconfig) +{ + int idx = mconfig->fmt_cfg_idx; + + if (mconfig->formats_config[idx].caps_size > 0) { + mconfig->formats_config[idx].caps = + devm_kzalloc(dev, mconfig->formats_config[idx].caps_size, + GFP_KERNEL); + if (!mconfig->formats_config[idx].caps) + return -ENOMEM; + memcpy(mconfig->formats_config[idx].caps, data, + mconfig->formats_config[idx].caps_size); + } + + return mconfig->formats_config[idx].caps_size; +} + /* * Parse the private data for the token and corresponding value. * The private data can have multiple data blocks. So, a data block @@ -2922,18 +2952,14 @@ static int skl_tplg_get_pvt_data(struct snd_soc_tplg_dapm_widget *tplg_w, if (block_type == SKL_TYPE_TUPLE) { ret = skl_tplg_get_tokens(dev, data, skl, mconfig, block_size); - - if (ret < 0) - return ret; - - --num_blocks; } else { - if (mconfig->formats_config.caps_size > 0) - memcpy(mconfig->formats_config.caps, data, - mconfig->formats_config.caps_size); - --num_blocks; - ret = mconfig->formats_config.caps_size; + ret = skl_tplg_get_caps_data(dev, data, mconfig); } + + if (ret < 0) + return ret; + + --num_blocks; off += ret; } @@ -3024,6 +3050,9 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt, int index, */ mconfig->id.module_id = -1; + /* To provide backward compatibility, set default as SKL_PARAM_INIT */ + mconfig->fmt_cfg_idx = SKL_PARAM_INIT; + /* Parse private data for tuples */ ret = skl_tplg_get_pvt_data(tplg_w, skl, bus->dev, mconfig); if (ret < 0) -- cgit v1.2.3