diff options
Diffstat (limited to 'sound/soc/intel/skylake/skl-topology.c')
-rw-r--r-- | sound/soc/intel/skylake/skl-topology.c | 83 |
1 files changed, 82 insertions, 1 deletions
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index dbe6a19b84f5..17da3b58c214 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -830,7 +830,7 @@ static int skl_fill_sink_instance_id(struct skl_sst *ctx, u32 *params, if (mcfg->m_type == SKL_MODULE_TYPE_KPB) { struct skl_kpb_params *kpb_params = (struct skl_kpb_params *)params; - struct skl_mod_inst_map *inst = kpb_params->map; + struct skl_mod_inst_map *inst = kpb_params->u.map; for (i = 0; i < kpb_params->num_modules; i++) { pvt_id = skl_get_pvt_instance_id_map(ctx, inst->mod_id, @@ -915,6 +915,87 @@ static int skl_tplg_set_module_bind_params(struct snd_soc_dapm_widget *w, return 0; } +static int skl_get_module_id(struct skl_sst *ctx, uuid_le *uuid) +{ + struct uuid_module *module; + + list_for_each_entry(module, &ctx->uuid_list, list) { + if (uuid_le_cmp(*uuid, module->uuid) == 0) + return module->id; + } + + return -EINVAL; +} + +static int skl_tplg_find_moduleid_from_uuid(struct skl *skl, + const struct snd_kcontrol_new *k) +{ + struct soc_bytes_ext *sb = (void *) k->private_value; + struct skl_algo_data *bc = (struct skl_algo_data *)sb->dobj.private; + struct skl_kpb_params *uuid_params, *params; + struct hdac_bus *bus = ebus_to_hbus(skl_to_ebus(skl)); + int i, size, module_id; + + if (bc->set_params == SKL_PARAM_BIND && bc->max) { + uuid_params = (struct skl_kpb_params *)bc->params; + size = uuid_params->num_modules * + sizeof(struct skl_mod_inst_map) + + sizeof(uuid_params->num_modules); + + params = devm_kzalloc(bus->dev, size, GFP_KERNEL); + if (!params) + return -ENOMEM; + + params->num_modules = uuid_params->num_modules; + + for (i = 0; i < uuid_params->num_modules; i++) { + module_id = skl_get_module_id(skl->skl_sst, + &uuid_params->u.map_uuid[i].mod_uuid); + if (module_id < 0) { + devm_kfree(bus->dev, params); + return -EINVAL; + } + + params->u.map[i].mod_id = module_id; + params->u.map[i].inst_id = + uuid_params->u.map_uuid[i].inst_id; + } + + devm_kfree(bus->dev, bc->params); + bc->params = (char *)params; + bc->max = size; + } + + return 0; +} + +/* + * Retrieve the module id from UUID mentioned in the + * post bind params + */ +void skl_tplg_add_moduleid_in_bind_params(struct skl *skl, + struct snd_soc_dapm_widget *w) +{ + struct skl_module_cfg *mconfig = w->priv; + int i; + + /* + * Post bind params are used for only for KPB + * to set copier instances to drain the data + * in fast mode + */ + if (mconfig->m_type != SKL_MODULE_TYPE_KPB) + return; + + for (i = 0; i < w->num_kcontrols; i++) + if ((w->kcontrol_news[i].access & + SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) && + (skl_tplg_find_moduleid_from_uuid(skl, + &w->kcontrol_news[i]) < 0)) + dev_err(skl->skl_sst->dev, + "%s: invalid kpb post bind params\n", + __func__); +} static int skl_tplg_module_add_deferred_bind(struct skl *skl, struct skl_module_cfg *src, struct skl_module_cfg *dst) |