Unverified Commit cf4484a0 authored by Mark Brown's avatar Mark Brown
Browse files

ASoC: qdsp6: audioreach: add multi-port, SAL and MFC support

Merge series from Srinivas Kandagatla <srinivas.kandagatla@linaro.org>:

This patchset adds support to multi-port connections between AudioReach Modules
which is required for sophisticated graphs like ECNS or Speaker Protection.
Also as part of ECNS testing new module support for SAL and MFC are added.

Tested on SM8450 with ECNS.
parents ad850421 6648a6dc
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -191,6 +191,33 @@ enum ar_event_types {
#define AR_TKN_U32_MODULE_SRC_INSTANCE_ID	208
#define AR_TKN_U32_MODULE_DST_INSTANCE_ID	209

#define AR_TKN_U32_MODULE_SRC_OP_PORT_ID1	210
#define AR_TKN_U32_MODULE_DST_IN_PORT_ID1	211
#define AR_TKN_U32_MODULE_DST_INSTANCE_ID1	212

#define AR_TKN_U32_MODULE_SRC_OP_PORT_ID2	213
#define AR_TKN_U32_MODULE_DST_IN_PORT_ID2	214
#define AR_TKN_U32_MODULE_DST_INSTANCE_ID2	215

#define AR_TKN_U32_MODULE_SRC_OP_PORT_ID3	216
#define AR_TKN_U32_MODULE_DST_IN_PORT_ID3	217
#define AR_TKN_U32_MODULE_DST_INSTANCE_ID3	218

#define AR_TKN_U32_MODULE_SRC_OP_PORT_ID4	219
#define AR_TKN_U32_MODULE_DST_IN_PORT_ID4	220
#define AR_TKN_U32_MODULE_DST_INSTANCE_ID4	221

#define AR_TKN_U32_MODULE_SRC_OP_PORT_ID5	222
#define AR_TKN_U32_MODULE_DST_IN_PORT_ID5	223
#define AR_TKN_U32_MODULE_DST_INSTANCE_ID5	224

#define AR_TKN_U32_MODULE_SRC_OP_PORT_ID6	225
#define AR_TKN_U32_MODULE_DST_IN_PORT_ID6	226
#define AR_TKN_U32_MODULE_DST_INSTANCE_ID6	227

#define AR_TKN_U32_MODULE_SRC_OP_PORT_ID7	228
#define AR_TKN_U32_MODULE_DST_IN_PORT_ID7	229
#define AR_TKN_U32_MODULE_DST_INSTANCE_ID7	230

#define AR_TKN_U32_MODULE_HW_IF_IDX		250
#define AR_TKN_U32_MODULE_HW_IF_TYPE		251
+219 −91
Original line number Diff line number Diff line
@@ -159,6 +159,8 @@ struct apm_module_hw_ep_mf_cfg {

#define APM_HW_EP_CFG_PSIZE ALIGN(sizeof(struct apm_module_hw_ep_mf_cfg), 8)

#define APM_MFC_CFG_PSIZE(p, n) ALIGN(struct_size(p, channel_mapping, n), 4)

struct apm_module_frame_size_factor_cfg {
	struct apm_module_param_data param_data;
	uint32_t frame_size_factor;
@@ -311,15 +313,6 @@ static void apm_populate_sub_graph_config(struct apm_sub_graph_data *cfg,
	cfg->sid.scenario_id = sg->scenario_id;
}

static void apm_populate_connection_obj(struct apm_module_conn_obj *obj,
					struct audioreach_module *module)
{
	obj->src_mod_inst_id = module->src_mod_inst_id;
	obj->src_mod_op_port_id = module->src_mod_op_port_id;
	obj->dst_mod_inst_id = module->instance_id;
	obj->dst_mod_ip_port_id = module->in_port;
}

static void apm_populate_module_prop_obj(struct apm_mod_prop_obj *obj,
					 struct audioreach_module *module)
{
@@ -332,63 +325,6 @@ static void apm_populate_module_prop_obj(struct apm_mod_prop_obj *obj,
	obj->prop_id_port.max_op_port = module->max_op_port;
}

struct audioreach_module *audioreach_get_container_last_module(
							struct audioreach_container *container)
{
	struct audioreach_module *module;

	list_for_each_entry(module, &container->modules_list, node) {
		if (module->dst_mod_inst_id == 0)
			return module;
	}

	return NULL;
}
EXPORT_SYMBOL_GPL(audioreach_get_container_last_module);

static bool is_module_in_container(struct audioreach_container *container, int module_iid)
{
	struct audioreach_module *module;

	list_for_each_entry(module, &container->modules_list, node) {
		if (module->instance_id == module_iid)
			return true;
	}

	return false;
}

struct audioreach_module *audioreach_get_container_first_module(
							struct audioreach_container *container)
{
	struct audioreach_module *module;

	/* get the first module from both connected or un-connected containers */
	list_for_each_entry(module, &container->modules_list, node) {
		if (module->src_mod_inst_id == 0 ||
		    !is_module_in_container(container, module->src_mod_inst_id))
			return module;
	}
	return NULL;
}
EXPORT_SYMBOL_GPL(audioreach_get_container_first_module);

struct audioreach_module *audioreach_get_container_next_module(
						struct audioreach_container *container,
						struct audioreach_module *module)
{
	int nmodule_iid = module->dst_mod_inst_id;
	struct audioreach_module *nmodule;

	list_for_each_entry(nmodule, &container->modules_list, node) {
		if (nmodule->instance_id == nmodule_iid)
			return nmodule;
	}

	return NULL;
}
EXPORT_SYMBOL_GPL(audioreach_get_container_next_module);

static void apm_populate_module_list_obj(struct apm_mod_list_obj *obj,
					 struct audioreach_container *container,
					 int sub_graph_id)
@@ -400,14 +336,15 @@ static void apm_populate_module_list_obj(struct apm_mod_list_obj *obj,
	obj->container_id = container->container_id;
	obj->num_modules = container->num_modules;
	i = 0;
	list_for_each_container_module(module, container) {
	list_for_each_entry(module, &container->modules_list, node) {
		obj->mod_cfg[i].module_id = module->module_id;
		obj->mod_cfg[i].instance_id = module->instance_id;
		i++;
	}
}

static void audioreach_populate_graph(struct apm_graph_open_params *open,
static void audioreach_populate_graph(struct q6apm *apm, struct audioreach_graph_info *info,
				      struct apm_graph_open_params *open,
				      struct list_head *sg_list,
				      int num_sub_graphs)
{
@@ -428,6 +365,16 @@ static void audioreach_populate_graph(struct apm_graph_open_params *open,

	mlobj = &ml_data->mod_list_obj[0];


	if (info->dst_mod_inst_id && info->src_mod_inst_id) {
		conn_obj = &mc_data->conn_obj[nconn];
		conn_obj->src_mod_inst_id = info->src_mod_inst_id;
		conn_obj->src_mod_op_port_id = info->src_mod_op_port_id;
		conn_obj->dst_mod_inst_id = info->dst_mod_inst_id;
		conn_obj->dst_mod_ip_port_id = info->dst_mod_ip_port_id;
		nconn++;
	}

	list_for_each_entry(sg, sg_list, node) {
		struct apm_sub_graph_data *sg_cfg = &sg_data->sg_cfg[i++];

@@ -439,30 +386,38 @@ static void audioreach_populate_graph(struct apm_graph_open_params *open,
			apm_populate_container_config(cobj, container);
			apm_populate_module_list_obj(mlobj, container, sg->sub_graph_id);

			list_for_each_container_module(module, container) {
				uint32_t src_mod_inst_id;

				src_mod_inst_id = module->src_mod_inst_id;
			list_for_each_entry(module, &container->modules_list, node) {
				int pn;

				module_prop_obj = &mp_data->mod_prop_obj[nmodule];
				module_prop_obj = &mp_data->mod_prop_obj[nmodule++];
				apm_populate_module_prop_obj(module_prop_obj, module);

				if (src_mod_inst_id) {
				if (!module->max_op_port)
					continue;

				for (pn = 0; pn < module->max_op_port; pn++) {
					if (module->dst_mod_inst_id[pn]) {
						conn_obj = &mc_data->conn_obj[nconn];
					apm_populate_connection_obj(conn_obj, module);
						conn_obj->src_mod_inst_id = module->instance_id;
						conn_obj->src_mod_op_port_id =
								module->src_mod_op_port_id[pn];
						conn_obj->dst_mod_inst_id =
								module->dst_mod_inst_id[pn];
						conn_obj->dst_mod_ip_port_id =
								module->dst_mod_ip_port_id[pn];
						nconn++;
					}

				nmodule++;
				}
			mlobj = (void *) mlobj + APM_MOD_LIST_OBJ_PSIZE(mlobj, container->num_modules);
			}
			mlobj = (void *) mlobj + APM_MOD_LIST_OBJ_PSIZE(mlobj,
									container->num_modules);

			ncontainer++;
		}
	}
}

void *audioreach_alloc_graph_pkt(struct q6apm *apm, struct list_head *sg_list, int graph_id)
void *audioreach_alloc_graph_pkt(struct q6apm *apm, struct audioreach_graph_info *info)
{
	int payload_size, sg_sz, cont_sz, ml_sz, mp_sz, mc_sz;
	struct apm_module_param_data  *param_data;
@@ -475,7 +430,7 @@ void *audioreach_alloc_graph_pkt(struct q6apm *apm, struct list_head *sg_list, i
	struct audioreach_module *module;
	struct audioreach_sub_graph *sgs;
	struct apm_mod_list_obj *mlobj;
	int num_modules_per_list;
	struct list_head *sg_list;
	int num_connections = 0;
	int num_containers = 0;
	int num_sub_graphs = 0;
@@ -484,24 +439,33 @@ void *audioreach_alloc_graph_pkt(struct q6apm *apm, struct list_head *sg_list, i
	struct gpr_pkt *pkt;
	void *p;

	sg_list = &info->sg_list;
	ml_sz = 0;

	/* add FE-BE connections */
	if (info->dst_mod_inst_id && info->src_mod_inst_id)
		num_connections++;

	list_for_each_entry(sgs, sg_list, node) {
		num_sub_graphs++;
		list_for_each_entry(container, &sgs->container_list, node) {
			num_containers++;
			num_modules += container->num_modules;
			list_for_each_container_module(module, container) {
				if (module->src_mod_inst_id)
					num_connections++;
			ml_sz = ml_sz + sizeof(struct apm_module_list_params) +
				APM_MOD_LIST_OBJ_PSIZE(mlobj, container->num_modules);

			list_for_each_entry(module, &container->modules_list, node) {
				num_connections += module->num_connections;
			}
		}
	}

	num_modules_list = num_containers;
	num_modules_per_list = num_modules/num_containers;
	sg_sz = APM_SUB_GRAPH_PSIZE(sg_params, num_sub_graphs);
	cont_sz = APM_CONTAINER_PSIZE(cont_params, num_containers);
	ml_sz =	ALIGN(sizeof(struct apm_module_list_params) +
		num_modules_list * APM_MOD_LIST_OBJ_PSIZE(mlobj,  num_modules_per_list), 8);

	ml_sz = ALIGN(ml_sz, 8);

	mp_sz = APM_MOD_PROP_PSIZE(mprop, num_modules);
	mc_sz =	APM_MOD_CONN_PSIZE(mcon, num_connections);

@@ -536,7 +500,7 @@ void *audioreach_alloc_graph_pkt(struct q6apm *apm, struct list_head *sg_list, i
	param_data->module_instance_id = APM_MODULE_INSTANCE_ID;
	param_data->param_id = APM_PARAM_ID_MODULE_LIST;
	param_data->param_size = ml_sz - APM_MODULE_PARAM_DATA_SIZE;
	params.mod_list_data->num_modules_list = num_sub_graphs;
	params.mod_list_data->num_modules_list = num_modules_list;
	p += ml_sz;

	/* Module Properties */
@@ -557,7 +521,7 @@ void *audioreach_alloc_graph_pkt(struct q6apm *apm, struct list_head *sg_list, i
	params.mod_conn_list_data->num_connections = num_connections;
	p += mc_sz;

	audioreach_populate_graph(&params, sg_list, num_sub_graphs);
	audioreach_populate_graph(apm, info, &params, sg_list, num_sub_graphs);

	return pkt;
}
@@ -696,6 +660,160 @@ static int audioreach_codec_dma_set_media_format(struct q6apm_graph *graph,
	return rc;
}

static int audioreach_sal_limiter_enable(struct q6apm_graph *graph,
					 struct audioreach_module *module, bool enable)
{
	struct apm_module_param_data *param_data;
	struct param_id_sal_limiter_enable *limiter_enable;
	int payload_size;
	struct gpr_pkt *pkt;
	int rc;
	void *p;

	payload_size = sizeof(*limiter_enable) + APM_MODULE_PARAM_DATA_SIZE;

	pkt = audioreach_alloc_apm_cmd_pkt(payload_size, APM_CMD_SET_CFG, 0);
	if (IS_ERR(pkt))
		return PTR_ERR(pkt);

	p = (void *)pkt + GPR_HDR_SIZE + APM_CMD_HDR_SIZE;

	param_data = p;
	param_data->module_instance_id = module->instance_id;
	param_data->error_code = 0;
	param_data->param_id = PARAM_ID_SAL_LIMITER_ENABLE;
	param_data->param_size = sizeof(*limiter_enable);
	p = p + APM_MODULE_PARAM_DATA_SIZE;
	limiter_enable = p;

	limiter_enable->enable_lim = enable;

	rc = q6apm_send_cmd_sync(graph->apm, pkt, 0);

	kfree(pkt);

	return rc;
}

static int audioreach_sal_set_media_format(struct q6apm_graph *graph,
					   struct audioreach_module *module,
					   struct audioreach_module_config *cfg)
{
	struct apm_module_param_data *param_data;
	struct param_id_sal_output_config *media_format;
	int payload_size;
	struct gpr_pkt *pkt;
	int rc;
	void *p;

	payload_size = sizeof(*media_format) + APM_MODULE_PARAM_DATA_SIZE;

	pkt = audioreach_alloc_apm_cmd_pkt(payload_size, APM_CMD_SET_CFG, 0);
	if (IS_ERR(pkt))
		return PTR_ERR(pkt);

	p = (void *)pkt + GPR_HDR_SIZE + APM_CMD_HDR_SIZE;

	param_data = p;
	param_data->module_instance_id = module->instance_id;
	param_data->error_code = 0;
	param_data->param_id = PARAM_ID_SAL_OUTPUT_CFG;
	param_data->param_size = sizeof(*media_format);
	p = p + APM_MODULE_PARAM_DATA_SIZE;
	media_format = p;

	media_format->bits_per_sample = cfg->bit_width;

	rc = q6apm_send_cmd_sync(graph->apm, pkt, 0);

	kfree(pkt);

	return rc;
}

static int audioreach_module_enable(struct q6apm_graph *graph,
				    struct audioreach_module *module,
				    bool enable)
{
	struct apm_module_param_data *param_data;
	struct param_id_module_enable *param;
	int payload_size;
	struct gpr_pkt *pkt;
	int rc;
	void *p;

	payload_size = sizeof(*param) + APM_MODULE_PARAM_DATA_SIZE;

	pkt = audioreach_alloc_apm_cmd_pkt(payload_size, APM_CMD_SET_CFG, 0);
	if (IS_ERR(pkt))
		return PTR_ERR(pkt);

	p = (void *)pkt + GPR_HDR_SIZE + APM_CMD_HDR_SIZE;

	param_data = p;
	param_data->module_instance_id = module->instance_id;
	param_data->error_code = 0;
	param_data->param_id = PARAM_ID_MODULE_ENABLE;
	param_data->param_size = sizeof(*param);
	p = p + APM_MODULE_PARAM_DATA_SIZE;
	param = p;

	param->enable = enable;

	rc = q6apm_send_cmd_sync(graph->apm, pkt, 0);

	kfree(pkt);

	return rc;
}

static int audioreach_mfc_set_media_format(struct q6apm_graph *graph,
					   struct audioreach_module *module,
					   struct audioreach_module_config *cfg)
{
	struct apm_module_param_data *param_data;
	struct param_id_mfc_media_format *media_format;
	uint32_t num_channels = cfg->num_channels;
	int payload_size;
	struct gpr_pkt *pkt;
	int rc;
	void *p;

	payload_size = APM_MFC_CFG_PSIZE(media_format, num_channels) +
		APM_MODULE_PARAM_DATA_SIZE;

	pkt = audioreach_alloc_apm_cmd_pkt(payload_size, APM_CMD_SET_CFG, 0);
	if (IS_ERR(pkt))
		return PTR_ERR(pkt);

	p = (void *)pkt + GPR_HDR_SIZE + APM_CMD_HDR_SIZE;

	param_data = p;
	param_data->module_instance_id = module->instance_id;
	param_data->error_code = 0;
	param_data->param_id = PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT;
	param_data->param_size = APM_MFC_CFG_PSIZE(media_format, num_channels);
	p = p + APM_MODULE_PARAM_DATA_SIZE;
	media_format = p;

	media_format->sample_rate = cfg->sample_rate;
	media_format->bit_width = cfg->bit_width;
	media_format->num_channels = cfg->num_channels;

	if (num_channels == 1) {
		media_format->channel_mapping[0] = PCM_CHANNEL_L;
	} else if (num_channels == 2) {
		media_format->channel_mapping[0] = PCM_CHANNEL_L;
		media_format->channel_mapping[1] = PCM_CHANNEL_R;
	}

	rc = q6apm_send_cmd_sync(graph->apm, pkt, 0);

	kfree(pkt);

	return rc;
}

static int audioreach_i2s_set_media_format(struct q6apm_graph *graph,
					   struct audioreach_module *module,
					   struct audioreach_module_config *cfg)
@@ -995,6 +1113,8 @@ int audioreach_set_media_format(struct q6apm_graph *graph, struct audioreach_mod

	switch (module->module_id) {
	case MODULE_ID_DATA_LOGGING:
		rc = audioreach_module_enable(graph, module, true);
		if (!rc)
			rc = audioreach_logging_set_media_format(graph, module);
		break;
	case MODULE_ID_PCM_DEC:
@@ -1016,6 +1136,14 @@ int audioreach_set_media_format(struct q6apm_graph *graph, struct audioreach_mod
	case MODULE_ID_CODEC_DMA_SOURCE:
		rc = audioreach_codec_dma_set_media_format(graph, module, cfg);
		break;
	case MODULE_ID_SAL:
		rc = audioreach_sal_set_media_format(graph, module, cfg);
		if (!rc)
			rc = audioreach_sal_limiter_enable(graph, module, true);
		break;
	case MODULE_ID_MFC:
		rc = audioreach_mfc_set_media_format(graph, module, cfg);
		break;
	default:
		rc = 0;
	}
+30 −17
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@ struct q6apm_graph;
#define MODULE_ID_PCM_CNV		0x07001003
#define MODULE_ID_PCM_ENC		0x07001004
#define MODULE_ID_PCM_DEC		0x07001005
#define MODULE_ID_SAL			0x07001010
#define MODULE_ID_MFC			0x07001015
#define MODULE_ID_CODEC_DMA_SINK	0x07001023
#define MODULE_ID_CODEC_DMA_SOURCE	0x07001024
#define MODULE_ID_I2S_SINK		0x0700100A
@@ -499,6 +501,16 @@ struct data_logging_config {
	uint32_t mode;
} __packed;

#define PARAM_ID_SAL_OUTPUT_CFG			0x08001016
struct param_id_sal_output_config {
	uint32_t bits_per_sample;
} __packed;

#define PARAM_ID_SAL_LIMITER_ENABLE		0x0800101E
struct param_id_sal_limiter_enable {
	uint32_t enable_lim;
} __packed;

#define PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT	0x08001024

struct param_id_mfc_media_format {
@@ -525,6 +537,11 @@ struct payload_media_fmt_pcm {
	uint8_t channel_mapping[];
} __packed;

#define PARAM_ID_MODULE_ENABLE			0x08001026
struct param_id_module_enable {
	uint32_t enable;
} __packed;

#define PARAM_ID_CODEC_DMA_INTF_CFG		0x08001063

struct param_id_codec_dma_intf_cfg {
@@ -595,7 +612,11 @@ struct audioreach_graph_info {
	int id;
	uint32_t num_sub_graphs;
	struct list_head sg_list;
	struct list_head connection_list;
	/* DPCM connection from FE Graph to BE graph */
	uint32_t src_mod_inst_id;
	uint32_t src_mod_op_port_id;
	uint32_t dst_mod_inst_id;
	uint32_t dst_mod_ip_port_id;
};

struct audioreach_sub_graph {
@@ -623,6 +644,8 @@ struct audioreach_container {
	struct audioreach_sub_graph *sub_graph;
};

#define AR_MAX_MOD_LINKS	8

struct audioreach_module {
	uint32_t module_id;
	uint32_t instance_id;
@@ -633,11 +656,12 @@ struct audioreach_module {
	uint32_t in_port;
	uint32_t out_port;

	uint32_t num_connections;
	/* Connections */
	uint32_t src_mod_inst_id;
	uint32_t src_mod_op_port_id;
	uint32_t dst_mod_inst_id;
	uint32_t dst_mod_ip_port_id;
	uint32_t src_mod_op_port_id[AR_MAX_MOD_LINKS];
	uint32_t dst_mod_inst_id[AR_MAX_MOD_LINKS];
	uint32_t dst_mod_ip_port_id[AR_MAX_MOD_LINKS];

	/* Format specifics */
	uint32_t ch_fmt;
@@ -694,9 +718,8 @@ void *audioreach_alloc_apm_pkt(int pkt_size, uint32_t opcode, uint32_t token,
void *audioreach_alloc_pkt(int payload_size, uint32_t opcode,
			   uint32_t token, uint32_t src_port,
			   uint32_t dest_port);
void *audioreach_alloc_graph_pkt(struct q6apm *apm,
				 struct list_head *sg_list,
				  int graph_id);
void *audioreach_alloc_graph_pkt(struct q6apm *apm, struct audioreach_graph_info
				 *info);
/* Topology specific */
int audioreach_tplg_init(struct snd_soc_component *component);

@@ -717,14 +740,4 @@ int audioreach_set_media_format(struct q6apm_graph *graph,
int audioreach_shared_memory_send_eos(struct q6apm_graph *graph);
int audioreach_gain_set_vol_ctrl(struct q6apm *apm,
				 struct audioreach_module *module, int vol);
struct audioreach_module *audioreach_get_container_last_module(
				struct audioreach_container *container);
struct audioreach_module *audioreach_get_container_first_module(
				struct audioreach_container *container);
struct audioreach_module *audioreach_get_container_next_module(
				struct audioreach_container *container,
				struct audioreach_module *module);
#define list_for_each_container_module(mod, cont) \
	for (mod = audioreach_get_container_first_module(cont); mod != NULL; \
	     mod = audioreach_get_container_next_module(cont, mod))
#endif /* __AUDIOREACH_H__ */
+2 −82
Original line number Diff line number Diff line
@@ -63,7 +63,7 @@ static struct audioreach_graph *q6apm_get_audioreach_graph(struct q6apm *apm, ui
	graph->info = info;
	graph->id = graph_id;

	graph->graph = audioreach_alloc_graph_pkt(apm, &info->sg_list, graph_id);
	graph->graph = audioreach_alloc_graph_pkt(apm, info);
	if (IS_ERR(graph->graph)) {
		void *err = graph->graph;

@@ -178,87 +178,6 @@ static struct audioreach_module *__q6apm_find_module_by_mid(struct q6apm *apm,
	return NULL;
}

static struct audioreach_module *q6apm_graph_get_last_module(struct q6apm *apm, u32 sgid)
{
	struct audioreach_container *container;
	struct audioreach_module *module;
	struct audioreach_sub_graph *sg;

	mutex_lock(&apm->lock);
	sg = idr_find(&apm->sub_graphs_idr, sgid);
	mutex_unlock(&apm->lock);
	if (!sg)
		return NULL;

	container = list_last_entry(&sg->container_list, struct audioreach_container, node);
	module = audioreach_get_container_last_module(container);

	return module;
}

static struct audioreach_module *q6apm_graph_get_first_module(struct q6apm *apm, u32 sgid)
{
	struct audioreach_container *container;
	struct audioreach_module *module;
	struct audioreach_sub_graph *sg;

	mutex_lock(&apm->lock);
	sg = idr_find(&apm->sub_graphs_idr, sgid);
	mutex_unlock(&apm->lock);
	if (!sg)
		return NULL;

	container = list_first_entry(&sg->container_list, struct audioreach_container, node);
	module = audioreach_get_container_first_module(container);

	return module;
}

bool q6apm_is_sub_graphs_connected(struct q6apm *apm, u32 src_sgid, u32 dst_sgid)
{
	struct audioreach_module *module;
	u32 iid;

	module = q6apm_graph_get_last_module(apm, src_sgid);
	if (!module)
		return false;

	iid = module->instance_id;
	module = q6apm_graph_get_first_module(apm, dst_sgid);
	if (!module)
		return false;

	if (module->src_mod_inst_id == iid)
		return true;

	return false;
}

int q6apm_connect_sub_graphs(struct q6apm *apm, u32 src_sgid, u32 dst_sgid, bool connect)
{
	struct audioreach_module *module;
	u32 iid;

	if (connect) {
		module = q6apm_graph_get_last_module(apm, src_sgid);
		if (!module)
			return -ENODEV;

		iid = module->instance_id;
	} else {
		iid = 0;
	}

	module = q6apm_graph_get_first_module(apm, dst_sgid);
	if (!module)
		return -ENODEV;

	/* set src module in dst subgraph first module */
	module->src_mod_inst_id = iid;

	return 0;
}

int q6apm_graph_media_format_shmem(struct q6apm_graph *graph,
				   struct audioreach_module_config *cfg)
{
@@ -731,6 +650,7 @@ static int apm_probe(gpr_device_t *gdev)
	apm->gdev = gdev;
	init_waitqueue_head(&apm->wait);

	INIT_LIST_HEAD(&apm->widget_list);
	idr_init(&apm->graph_idr);
	idr_init(&apm->graph_info_idr);
	idr_init(&apm->sub_graphs_idr);
+1 −5
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ struct q6apm {
	struct mutex lock;
	uint32_t state;

	struct list_head widget_list;
	struct idr graph_idr;
	struct idr graph_info_idr;
	struct idr sub_graphs_idr;
@@ -141,12 +142,7 @@ int q6apm_send_cmd_sync(struct q6apm *apm, struct gpr_pkt *pkt,
/* Callback for graph specific */
struct audioreach_module *q6apm_find_module_by_mid(struct q6apm_graph *graph,
						    uint32_t mid);

void q6apm_set_fe_dai_ops(struct snd_soc_dai_driver *dai_drv);
int q6apm_connect_sub_graphs(struct q6apm *apm, u32 src_sgid, u32 dst_sgid,
			     bool connect);
bool q6apm_is_sub_graphs_connected(struct q6apm *apm, u32 src_sgid,
				   u32 dst_sgid);
int q6apm_graph_get_rx_shmem_module_iid(struct q6apm_graph *graph);

#endif /* __APM_GRAPH_ */
Loading