summaryrefslogtreecommitdiffstats
path: root/sound/soc/intel/skylake/skl-topology.c
diff options
context:
space:
mode:
authorKareem Shaik <kareem.m.shaik@intel.com>2021-08-18 09:57:39 +0200
committerMark Brown <broonie@kernel.org>2021-08-23 16:40:02 +0100
commita4ad42d28618eef83bee02e0a19af0d467bd9722 (patch)
tree268c3f1ea91dab421f4efe1212e0c97d94cc9471 /sound/soc/intel/skylake/skl-topology.c
parente4e95d8291831fa63c32e00b59f544f0812dc0b6 (diff)
downloadlinux-a4ad42d28618eef83bee02e0a19af0d467bd9722.tar.bz2
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 <kareem.m.shaik@intel.com> Signed-off-by: Gustaw Lewandowski <gustaw.lewandowski@linux.intel.com> Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com> Tested-by: Lukasz Majczak <lma@semihalf.com> Link: https://lore.kernel.org/r/20210818075742.1515155-9-cezary.rojewski@intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/intel/skylake/skl-topology.c')
-rw-r--r--sound/soc/intel/skylake/skl-topology.c99
1 files changed, 64 insertions, 35 deletions
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)