[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, &param_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