summaryrefslogtreecommitdiff
path: root/sound/soc/intel
diff options
context:
space:
mode:
authorAmadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>2022-12-14 21:55:00 +0300
committerMark Brown <broonie@kernel.org>2022-12-26 02:33:05 +0300
commit29d6523698f68011eda67619faa6358a46952e96 (patch)
tree61e74996d1d9d399294b18de77347b934508e6aa /sound/soc/intel
parentbe2b81b519d7121290cfecc5fdfb4907ecc41c39 (diff)
downloadlinux-29d6523698f68011eda67619faa6358a46952e96.tar.xz
ASoC: Intel: avs: Peakvol module configuration
Handle creation of peakvol module in FW. When peakvol module is created it retrieves actual value from kcontrol and sends it to FW as part of configuration 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-5-amadeuszx.slawinski@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/intel')
-rw-r--r--sound/soc/intel/avs/path.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/sound/soc/intel/avs/path.c b/sound/soc/intel/avs/path.c
index ce157a8d6552..05302ab705ae 100644
--- a/sound/soc/intel/avs/path.c
+++ b/sound/soc/intel/avs/path.c
@@ -10,6 +10,7 @@
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include "avs.h"
+#include "control.h"
#include "path.h"
#include "topology.h"
@@ -264,6 +265,65 @@ static int avs_copier_create(struct avs_dev *adev, struct avs_path_module *mod)
return ret;
}
+static struct avs_control_data *avs_get_module_control(struct avs_path_module *mod)
+{
+ struct avs_tplg_module *t = mod->template;
+ struct avs_tplg_path_template *path_tmpl;
+ struct snd_soc_dapm_widget *w;
+ int i;
+
+ path_tmpl = t->owner->owner->owner;
+ w = path_tmpl->w;
+
+ for (i = 0; i < w->num_kcontrols; i++) {
+ struct avs_control_data *ctl_data;
+ struct soc_mixer_control *mc;
+
+ mc = (struct soc_mixer_control *)w->kcontrols[i]->private_value;
+ ctl_data = (struct avs_control_data *)mc->dobj.private;
+ if (ctl_data->id == t->ctl_id)
+ return ctl_data;
+ }
+
+ return NULL;
+}
+
+static int avs_peakvol_create(struct avs_dev *adev, struct avs_path_module *mod)
+{
+ struct avs_tplg_module *t = mod->template;
+ struct avs_control_data *ctl_data;
+ struct avs_peakvol_cfg *cfg;
+ int volume = S32_MAX;
+ size_t size;
+ int ret;
+
+ ctl_data = avs_get_module_control(mod);
+ if (ctl_data)
+ volume = ctl_data->volume;
+
+ /* As 2+ channels controls are unsupported, have a single block for all channels. */
+ size = struct_size(cfg, vols, 1);
+ cfg = kzalloc(size, GFP_KERNEL);
+ if (!cfg)
+ return -ENOMEM;
+
+ cfg->base.cpc = t->cfg_base->cpc;
+ cfg->base.ibs = t->cfg_base->ibs;
+ cfg->base.obs = t->cfg_base->obs;
+ cfg->base.is_pages = t->cfg_base->is_pages;
+ cfg->base.audio_fmt = *t->in_fmt;
+ cfg->vols[0].target_volume = volume;
+ cfg->vols[0].channel_id = AVS_ALL_CHANNELS_MASK;
+ cfg->vols[0].curve_type = AVS_AUDIO_CURVE_NONE;
+ cfg->vols[0].curve_duration = 0;
+
+ ret = avs_dsp_init_module(adev, mod->module_id, mod->owner->instance_id, t->core_id,
+ t->domain, cfg, size, &mod->instance_id);
+
+ kfree(cfg);
+ return ret;
+}
+
static int avs_updown_mix_create(struct avs_dev *adev, struct avs_path_module *mod)
{
struct avs_tplg_module *t = mod->template;
@@ -465,6 +525,8 @@ static struct avs_module_create avs_module_create[] = {
{ &AVS_MIXOUT_MOD_UUID, avs_modbase_create },
{ &AVS_KPBUFF_MOD_UUID, avs_modbase_create },
{ &AVS_COPIER_MOD_UUID, avs_copier_create },
+ { &AVS_PEAKVOL_MOD_UUID, avs_peakvol_create },
+ { &AVS_GAIN_MOD_UUID, avs_peakvol_create },
{ &AVS_MICSEL_MOD_UUID, avs_micsel_create },
{ &AVS_MUX_MOD_UUID, avs_mux_create },
{ &AVS_UPDWMIX_MOD_UUID, avs_updown_mix_create },