[alsa-devel] [PATCH 5/6] ASoC: Intel: Skylake: Add DSP module init and binding routines
Vinod Koul
vinod.koul at intel.com
Tue Jul 21 20:23:59 CEST 2015
From: Jeeja KP <jeeja.kp at intel.com>
The modules init and binding helper function creates module init and bind
IPC message based on module parameter and calls IPC interface to send the
IPC to DSP FW.
Signed-off-by: Jeeja KP <jeeja.kp at intel.com>
Signed-off-by: Vinod Koul <vinod.koul at intel.com>
---
sound/soc/intel/skylake/skl-messages.c | 165 +++++++++++++++++++++++++++++++++
sound/soc/intel/skylake/skl-topology.h | 4 +
2 files changed, 169 insertions(+)
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c
index faa0e71d4ae5..72af582183ae 100644
--- a/sound/soc/intel/skylake/skl-messages.c
+++ b/sound/soc/intel/skylake/skl-messages.c
@@ -547,3 +547,168 @@ static int skl_free_queue(struct skl_module_pin *mpin,
return m_pin.pin_index;
}
+
+int skl_init_module(struct skl_sst *ctx,
+ struct skl_module_cfg *mconfig, char *param)
+{
+ u16 module_config_size = 0;
+ void *param_data = NULL;
+ int ret;
+ struct skl_ipc_init_instance_msg msg;
+
+ dev_dbg(ctx->dev, "%s: module_id = %d instance=%d\n", __func__,
+ mconfig->id.module_id, mconfig->id.instance_id);
+
+ if (mconfig->pipe->state != SKL_PIPE_CREATED) {
+ dev_err(ctx->dev, "Pipe not created state= %d pipe_id= %d\n",
+ mconfig->pipe->state, mconfig->pipe->ppl_id);
+ return -EIO;
+ }
+
+ ret = skl_set_module_format(ctx, mconfig,
+ &module_config_size, ¶m_data);
+ if (ret < 0) {
+ dev_err(ctx->dev, "Failed to set module format ret=%d\n", ret);
+ return ret;
+ }
+
+ msg.module_id = mconfig->id.module_id;
+ msg.instance_id = mconfig->id.instance_id;
+ msg.ppl_instance_id = mconfig->pipe->ppl_id;
+ msg.param_data_size = module_config_size;
+ msg.core_id = mconfig->core_id;
+
+ ret = skl_ipc_init_instance(&ctx->ipc, &msg, param_data);
+ if (ret < 0) {
+ dev_err(ctx->dev, "Failed to init instance ret=%d\n", ret);
+ kfree(param_data);
+ return ret;
+ }
+ mconfig->m_state = SKL_MODULE_INIT_DONE;
+
+ return ret;
+}
+
+static int skl_unbind_modules(struct skl_sst *ctx,
+ struct skl_module_cfg *src_mcfg,
+ struct skl_module_cfg *dst_mcfg)
+{
+ int ret;
+ struct skl_ipc_bind_unbind_msg msg;
+ struct skl_module_inst_id src_id = src_mcfg->id;
+ struct skl_module_inst_id dst_id = dst_mcfg->id;
+ int in_max = dst_mcfg->max_in_queue;
+ int out_max = src_mcfg->max_out_queue;
+ struct skl_module_pin m_pin;
+
+ if (src_mcfg->m_state != SKL_MODULE_BIND_DONE)
+ return 0;
+
+ /*
+ * if intra module unbind, check if both modules are BIND,
+ * then send unbind
+ */
+ if ((src_mcfg->pipe->ppl_id != dst_mcfg->pipe->ppl_id) &&
+ dst_mcfg->m_state != SKL_MODULE_BIND_DONE)
+ return 0;
+ else if (src_mcfg->m_state < SKL_MODULE_INIT_DONE &&
+ dst_mcfg->m_state < SKL_MODULE_INIT_DONE)
+ return 0;
+
+ /* get src pin index */
+ m_pin = skl_get_queue(src_mcfg->m_out_pin, src_id, out_max);
+ if (m_pin.pin_index < 0)
+ return -EINVAL;
+
+ msg.src_queue = m_pin.pin_index;
+
+ /* get dst pin index */
+ m_pin = skl_get_queue(dst_mcfg->m_in_pin, dst_id, in_max);
+ if (m_pin.pin_index < 0) {
+ skl_free_queue(src_mcfg->m_out_pin, src_id, out_max);
+ return -EINVAL;
+ }
+
+ msg.dst_queue = m_pin.pin_index;
+
+ msg.module_id = src_mcfg->id.module_id;
+ msg.instance_id = src_mcfg->id.instance_id;
+ msg.dst_module_id = dst_mcfg->id.module_id;
+ msg.dst_instance_id = dst_mcfg->id.instance_id;
+ msg.bind = false;
+
+ ret = skl_ipc_bind_unbind(&ctx->ipc, &msg);
+ if (!ret)
+ src_mcfg->m_state = SKL_MODULE_UNINIT;
+
+ skl_free_queue(src_mcfg->m_out_pin, src_id, out_max);
+ skl_free_queue(dst_mcfg->m_in_pin, dst_id, in_max);
+
+ return ret;
+}
+
+static int skl_bind_modules(struct skl_sst *ctx,
+ struct skl_module_cfg *src_mcfg,
+ struct skl_module_cfg *dst_mcfg)
+{
+ int pin_index, ret;
+ struct skl_ipc_bind_unbind_msg msg;
+ struct skl_module_inst_id src_id = src_mcfg->id;
+ struct skl_module_inst_id dst_id = dst_mcfg->id;
+ int in_max = dst_mcfg->max_in_queue;
+ int out_max = src_mcfg->max_out_queue;
+
+ if (src_mcfg->m_state < SKL_MODULE_INIT_DONE &&
+ dst_mcfg->m_state < SKL_MODULE_INIT_DONE)
+ return 0;
+
+ pin_index = skl_alloc_queue(src_mcfg->m_out_pin, src_id, out_max);
+ if (pin_index < 0)
+ return -EINVAL;
+
+ msg.src_queue = pin_index;
+ pin_index = skl_alloc_queue(dst_mcfg->m_in_pin, dst_id, in_max);
+ if (pin_index < 0) {
+ skl_free_queue(src_mcfg->m_out_pin, src_id, out_max);
+ return -EINVAL;
+ }
+
+ msg.dst_queue = pin_index;
+ dev_dbg(ctx->dev, "src queue = %d dst queue =%d\n",
+ msg.src_queue, msg.dst_queue);
+
+ msg.module_id = src_mcfg->id.module_id;
+ msg.instance_id = src_mcfg->id.instance_id;
+ msg.dst_module_id = dst_mcfg->id.module_id;
+ msg.dst_instance_id = dst_mcfg->id.instance_id;
+ msg.bind = true;
+
+ ret = skl_ipc_bind_unbind(&ctx->ipc, &msg);
+
+ if (!ret) {
+ src_mcfg->m_state = SKL_MODULE_BIND_DONE;
+ } else {
+ /* error case , if IPC fails, clear the queue index */
+ skl_free_queue(src_mcfg->m_out_pin, src_id, out_max);
+ skl_free_queue(dst_mcfg->m_in_pin, dst_id, in_max);
+ }
+
+ return ret;
+}
+
+int skl_bind_unbind_modules(struct skl_sst *ctx, struct skl_module_cfg
+ *src_module, struct skl_module_cfg *dst_module, bool bind)
+{
+ dev_dbg(ctx->dev, "%s: src module_id = %d src_instance=%d\n",
+ __func__, src_module->id.module_id, src_module->id.instance_id);
+ dev_dbg(ctx->dev, "%s: dst_module=%d dst_instacne=%d\n", __func__,
+ dst_module->id.module_id, dst_module->id.instance_id);
+
+ dev_dbg(ctx->dev, "src_module state = %d dst module state = %d\n",
+ src_module->m_state, dst_module->m_state);
+
+ if (bind)
+ return skl_bind_modules(ctx, src_module, dst_module);
+ else
+ return skl_unbind_modules(ctx, src_module, dst_module);
+}
diff --git a/sound/soc/intel/skylake/skl-topology.h b/sound/soc/intel/skylake/skl-topology.h
index e4b2a339b2f4..c944ec024e62 100644
--- a/sound/soc/intel/skylake/skl-topology.h
+++ b/sound/soc/intel/skylake/skl-topology.h
@@ -263,5 +263,9 @@ struct skl_module_cfg {
struct skl_specific_cfg formats_config;
};
+int skl_init_module(struct skl_sst *ctx, struct skl_module_cfg *module_config,
+ char *param);
+int skl_bind_unbind_modules(struct skl_sst *ctx, struct skl_module_cfg
+ *src_module, struct skl_module_cfg *dst_module, bool bind);
enum skl_bitdepth skl_get_bit_depth(int params);
#endif
--
1.9.1
More information about the Alsa-devel
mailing list