summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeeja KP <jeeja.kp@intel.com>2015-11-28 15:01:49 +0530
committerMark Brown <broonie@kernel.org>2015-12-01 22:17:00 +0000
commitabb740033b56a2f57582e8e26bb9ea3650b6a3cc (patch)
tree7c16babc93c2a43f45f15d6c8e5f6bc65f4cda94
parent399b210bef097ce01d9e7b03ce5d4435f0624111 (diff)
ASoC: Intel: Skylake: Add support to configure module params
This adds support to configure module parameter during module initialization or after module init using set module param required by the DSP firmware sequence. Signed-off-by: Jeeja KP <jeeja.kp@intel.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/intel/skylake/skl-topology.c87
-rw-r--r--sound/soc/intel/skylake/skl-topology.h9
2 files changed, 95 insertions, 1 deletions
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c
index 7a03bea48a9a..bfc138df56bc 100644
--- a/sound/soc/intel/skylake/skl-topology.c
+++ b/sound/soc/intel/skylake/skl-topology.c
@@ -314,6 +314,83 @@ static int skl_tplg_alloc_pipe_widget(struct device *dev,
}
/*
+ * some modules can have multiple params set from user control and
+ * need to be set after module is initialized. If set_param flag is
+ * set module params will be done after module is initialised.
+ */
+static int skl_tplg_set_module_params(struct snd_soc_dapm_widget *w,
+ struct skl_sst *ctx)
+{
+ int i, ret;
+ struct skl_module_cfg *mconfig = w->priv;
+ const struct snd_kcontrol_new *k;
+ struct soc_bytes_ext *sb;
+ struct skl_algo_data *bc;
+ struct skl_specific_cfg *sp_cfg;
+
+ if (mconfig->formats_config.caps_size > 0 &&
+ mconfig->formats_config.set_params) {
+ sp_cfg = &mconfig->formats_config;
+ ret = skl_set_module_params(ctx, sp_cfg->caps,
+ sp_cfg->caps_size,
+ sp_cfg->param_id, mconfig);
+ if (ret < 0)
+ return ret;
+ }
+
+ for (i = 0; i < w->num_kcontrols; i++) {
+ k = &w->kcontrol_news[i];
+ if (k->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
+ sb = (void *) k->private_value;
+ bc = (struct skl_algo_data *)sb->dobj.private;
+
+ if (bc->set_params) {
+ ret = skl_set_module_params(ctx,
+ (u32 *)bc->params, bc->max,
+ bc->param_id, mconfig);
+ if (ret < 0)
+ return ret;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * some module param can set from user control and this is required as
+ * when module is initailzed. if module param is required in init it is
+ * identifed by set_param flag. if set_param flag is not set, then this
+ * parameter needs to set as part of module init.
+ */
+static int skl_tplg_set_module_init_data(struct snd_soc_dapm_widget *w)
+{
+ const struct snd_kcontrol_new *k;
+ struct soc_bytes_ext *sb;
+ struct skl_algo_data *bc;
+ struct skl_module_cfg *mconfig = w->priv;
+ int i;
+
+ for (i = 0; i < w->num_kcontrols; i++) {
+ k = &w->kcontrol_news[i];
+ if (k->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
+ sb = (struct soc_bytes_ext *)k->private_value;
+ bc = (struct skl_algo_data *)sb->dobj.private;
+
+ if (bc->set_params)
+ continue;
+
+ mconfig->formats_config.caps = (u32 *)&bc->params;
+ mconfig->formats_config.caps_size = bc->max;
+
+ break;
+ }
+ }
+
+ return 0;
+}
+
+/*
* Inside a pipe instance, we can have various modules. These modules need
* to instantiated in DSP by invoking INIT_MODULE IPC, which is achieved by
* skl_init_module() routine, so invoke that for all modules in a pipeline
@@ -340,9 +417,15 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe)
* FE/BE params
*/
skl_tplg_update_module_params(w, ctx);
+
+ skl_tplg_set_module_init_data(w);
ret = skl_init_module(ctx, mconfig);
if (ret < 0)
return ret;
+
+ ret = skl_tplg_set_module_params(w, ctx);
+ if (ret < 0)
+ return ret;
}
return 0;
@@ -1215,7 +1298,9 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt,
return -ENOMEM;
memcpy(mconfig->formats_config.caps, dfw_config->caps.caps,
- dfw_config->caps.caps_size);
+ dfw_config->caps.caps_size);
+ mconfig->formats_config.param_id = dfw_config->caps.param_id;
+ mconfig->formats_config.set_params = dfw_config->caps.set_params;
bind_event:
if (tplg_w->event_type == 0) {
diff --git a/sound/soc/intel/skylake/skl-topology.h b/sound/soc/intel/skylake/skl-topology.h
index 0a66fab59828..51e785424a37 100644
--- a/sound/soc/intel/skylake/skl-topology.h
+++ b/sound/soc/intel/skylake/skl-topology.h
@@ -206,6 +206,8 @@ struct skl_module_pin {
};
struct skl_specific_cfg {
+ bool set_params;
+ u32 param_id;
u32 caps_size;
u32 *caps;
};
@@ -284,6 +286,13 @@ struct skl_module_cfg {
struct skl_specific_cfg formats_config;
};
+struct skl_algo_data {
+ u32 param_id;
+ bool set_params;
+ u32 max;
+ char *params;
+};
+
struct skl_pipeline {
struct skl_pipe *pipe;
struct list_head node;