ASoC: Intel: avs: Parse control tuples

Add callback to handle loading of kcontrol and linking it to active
widget. In order to link kcontrol to specific modules add additional
field to module data, as well as specify control id in kcontrol data.

Co-authored-by: Cezary Rojewski <cezary.rojewski@intel.com>
Signed-off-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
Link: https://lore.kernel.org/r/20221214185500.3896902-4-amadeuszx.slawinski@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Amadeusz Sławiński 2022-12-14 19:54:59 +01:00 committed by Mark Brown
parent 585b9427ed
commit be2b81b519
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
4 changed files with 93 additions and 0 deletions

View File

@ -108,6 +108,7 @@ enum avs_tplg_token {
AVS_TKN_MOD_CORE_ID_U8 = 1704,
AVS_TKN_MOD_PROC_DOMAIN_U8 = 1705,
AVS_TKN_MOD_MODCFG_EXT_ID_U32 = 1706,
AVS_TKN_MOD_KCONTROL_ID_U32 = 1707,
/* struct avs_tplg_path_template */
AVS_TKN_PATH_TMPL_ID_U32 = 1801,
@ -121,6 +122,9 @@ enum avs_tplg_token {
AVS_TKN_PIN_FMT_INDEX_U32 = 2201,
AVS_TKN_PIN_FMT_IOBS_U32 = 2202,
AVS_TKN_PIN_FMT_AFMT_ID_U32 = 2203,
/* struct avs_tplg_kcontrol */
AVS_TKN_KCONTROL_ID_U32 = 2301,
};
#endif

View File

@ -23,6 +23,16 @@ static struct avs_dev *avs_get_kcontrol_adev(struct snd_kcontrol *kcontrol)
static struct avs_path_module *avs_get_kcontrol_module(struct avs_dev *adev, u32 id)
{
struct avs_path *path;
struct avs_path_pipeline *ppl;
struct avs_path_module *mod;
list_for_each_entry(path, &adev->path_list, node)
list_for_each_entry(ppl, &path->ppl_list, node)
list_for_each_entry(mod, &ppl->mod_list, node)
if (mod->template->ctl_id && mod->template->ctl_id == id)
return mod;
return NULL;
}

View File

@ -13,6 +13,7 @@
#include <sound/soc-topology.h>
#include <uapi/sound/intel/avs/tokens.h>
#include "avs.h"
#include "control.h"
#include "topology.h"
/* Get pointer to vendor array at the specified offset. */
@ -1070,6 +1071,12 @@ static const struct avs_tplg_token_parser module_parsers[] = {
.offset = offsetof(struct avs_tplg_module, cfg_ext),
.parse = avs_parse_modcfg_ext_ptr,
},
{
.token = AVS_TKN_MOD_KCONTROL_ID_U32,
.type = SND_SOC_TPLG_TUPLE_TYPE_WORD,
.offset = offsetof(struct avs_tplg_module, ctl_id),
.parse = avs_parse_byte_token,
},
};
static struct avs_tplg_module *
@ -1435,6 +1442,16 @@ static int avs_widget_load(struct snd_soc_component *comp, int index,
return 0;
}
static int avs_widget_ready(struct snd_soc_component *comp, int index,
struct snd_soc_dapm_widget *w,
struct snd_soc_tplg_dapm_widget *dw)
{
struct avs_tplg_path_template *template = w->priv;
template->w = w;
return 0;
}
static int avs_dai_load(struct snd_soc_component *comp, int index,
struct snd_soc_dai_driver *dai_drv, struct snd_soc_tplg_pcm *pcm,
struct snd_soc_dai *dai)
@ -1586,9 +1603,68 @@ static int avs_manifest(struct snd_soc_component *comp, int index,
return avs_tplg_parse_bindings(comp, tuples, remaining);
}
#define AVS_CONTROL_OPS_VOLUME 257
static const struct snd_soc_tplg_kcontrol_ops avs_control_ops[] = {
{
.id = AVS_CONTROL_OPS_VOLUME,
.get = avs_control_volume_get,
.put = avs_control_volume_put,
},
};
static const struct avs_tplg_token_parser control_parsers[] = {
{
.token = AVS_TKN_KCONTROL_ID_U32,
.type = SND_SOC_TPLG_TUPLE_TYPE_WORD,
.offset = offsetof(struct avs_control_data, id),
.parse = avs_parse_word_token,
},
};
static int
avs_control_load(struct snd_soc_component *comp, int index, struct snd_kcontrol_new *ctmpl,
struct snd_soc_tplg_ctl_hdr *hdr)
{
struct snd_soc_tplg_vendor_array *tuples;
struct snd_soc_tplg_mixer_control *tmc;
struct avs_control_data *ctl_data;
struct soc_mixer_control *mc;
size_t block_size;
int ret;
switch (hdr->type) {
case SND_SOC_TPLG_TYPE_MIXER:
tmc = container_of(hdr, typeof(*tmc), hdr);
tuples = tmc->priv.array;
block_size = le32_to_cpu(tmc->priv.size);
break;
default:
return -EINVAL;
}
ctl_data = devm_kzalloc(comp->card->dev, sizeof(*ctl_data), GFP_KERNEL);
if (!ctl_data)
return -ENOMEM;
ret = parse_dictionary_entries(comp, tuples, block_size, ctl_data, 1, sizeof(*ctl_data),
AVS_TKN_KCONTROL_ID_U32, control_parsers,
ARRAY_SIZE(control_parsers));
if (ret)
return ret;
mc = (struct soc_mixer_control *)ctmpl->private_value;
mc->dobj.private = ctl_data;
return 0;
}
static struct snd_soc_tplg_ops avs_tplg_ops = {
.io_ops = avs_control_ops,
.io_ops_count = ARRAY_SIZE(avs_control_ops),
.control_load = avs_control_load,
.dapm_route_load = avs_route_load,
.widget_load = avs_widget_load,
.widget_ready = avs_widget_ready,
.dai_load = avs_dai_load,
.link_load = avs_link_load,
.manifest = avs_manifest,

View File

@ -138,6 +138,8 @@ struct avs_tplg_path_template_id {
struct avs_tplg_path_template {
u32 id;
struct snd_soc_dapm_widget *w;
struct list_head path_list;
struct avs_tplg *owner;
@ -180,6 +182,7 @@ struct avs_tplg_module {
u8 core_id;
u8 domain;
struct avs_tplg_modcfg_ext *cfg_ext;
u32 ctl_id;
struct avs_tplg_pipeline *owner;
/* Pipeline modules management. */