xref: /openbmc/linux/sound/soc/qcom/qdsp6/audioreach.c (revision 2c954a37)
144c28dbdSSrinivas Kandagatla // SPDX-License-Identifier: GPL-2.0
244c28dbdSSrinivas Kandagatla // Copyright (c) 2020, Linaro Limited
344c28dbdSSrinivas Kandagatla 
444c28dbdSSrinivas Kandagatla #include <linux/kernel.h>
544c28dbdSSrinivas Kandagatla #include <linux/slab.h>
644c28dbdSSrinivas Kandagatla #include <linux/soc/qcom/apr.h>
725ab80dbSSrinivas Kandagatla #include <sound/soc.h>
825ab80dbSSrinivas Kandagatla #include <sound/soc-dai.h>
925ab80dbSSrinivas Kandagatla #include <sound/pcm.h>
1025ab80dbSSrinivas Kandagatla #include <sound/pcm_params.h>
1144c28dbdSSrinivas Kandagatla #include <dt-bindings/soc/qcom,gpr.h>
125477518bSSrinivas Kandagatla #include "q6apm.h"
1344c28dbdSSrinivas Kandagatla #include "audioreach.h"
1444c28dbdSSrinivas Kandagatla 
1544c28dbdSSrinivas Kandagatla /* SubGraph Config */
1644c28dbdSSrinivas Kandagatla struct apm_sub_graph_data {
1744c28dbdSSrinivas Kandagatla 	struct apm_sub_graph_cfg sub_graph_cfg;
1844c28dbdSSrinivas Kandagatla 	struct apm_prop_data perf_data;
1944c28dbdSSrinivas Kandagatla 	struct apm_sg_prop_id_perf_mode perf;
2044c28dbdSSrinivas Kandagatla 	struct apm_prop_data dir_data;
2144c28dbdSSrinivas Kandagatla 	struct apm_sg_prop_id_direction dir;
2244c28dbdSSrinivas Kandagatla 	struct apm_prop_data sid_data;
2344c28dbdSSrinivas Kandagatla 	struct apm_sg_prop_id_scenario_id sid;
2444c28dbdSSrinivas Kandagatla 
2544c28dbdSSrinivas Kandagatla } __packed;
2644c28dbdSSrinivas Kandagatla 
2744c28dbdSSrinivas Kandagatla #define APM_SUB_GRAPH_CFG_NPROP	3
2844c28dbdSSrinivas Kandagatla 
2944c28dbdSSrinivas Kandagatla struct apm_sub_graph_params  {
3044c28dbdSSrinivas Kandagatla 	struct apm_module_param_data param_data;
3144c28dbdSSrinivas Kandagatla 	uint32_t num_sub_graphs;
3244c28dbdSSrinivas Kandagatla 	struct apm_sub_graph_data sg_cfg[];
3344c28dbdSSrinivas Kandagatla } __packed;
3444c28dbdSSrinivas Kandagatla 
3544c28dbdSSrinivas Kandagatla #define APM_SUB_GRAPH_PSIZE(p, n) ALIGN(struct_size(p, sg_cfg, n), 8)
3644c28dbdSSrinivas Kandagatla 
3744c28dbdSSrinivas Kandagatla /* container config */
3844c28dbdSSrinivas Kandagatla struct apm_container_obj  {
3944c28dbdSSrinivas Kandagatla 	struct apm_container_cfg container_cfg;
4044c28dbdSSrinivas Kandagatla 	/* Capability ID list */
4144c28dbdSSrinivas Kandagatla 	struct apm_prop_data cap_data;
4244c28dbdSSrinivas Kandagatla 	uint32_t num_capability_id;
4344c28dbdSSrinivas Kandagatla 	uint32_t capability_id;
4444c28dbdSSrinivas Kandagatla 
4544c28dbdSSrinivas Kandagatla 	/* Container graph Position */
4644c28dbdSSrinivas Kandagatla 	struct apm_prop_data pos_data;
4744c28dbdSSrinivas Kandagatla 	struct apm_cont_prop_id_graph_pos pos;
4844c28dbdSSrinivas Kandagatla 
4944c28dbdSSrinivas Kandagatla 	/* Container Stack size */
5044c28dbdSSrinivas Kandagatla 	struct apm_prop_data stack_data;
5144c28dbdSSrinivas Kandagatla 	struct apm_cont_prop_id_stack_size stack;
5244c28dbdSSrinivas Kandagatla 
5344c28dbdSSrinivas Kandagatla 	/* Container proc domain id */
5444c28dbdSSrinivas Kandagatla 	struct apm_prop_data domain_data;
5544c28dbdSSrinivas Kandagatla 	struct apm_cont_prop_id_domain domain;
5644c28dbdSSrinivas Kandagatla } __packed;
5744c28dbdSSrinivas Kandagatla 
5844c28dbdSSrinivas Kandagatla struct apm_container_params  {
5944c28dbdSSrinivas Kandagatla 	struct apm_module_param_data param_data;
6044c28dbdSSrinivas Kandagatla 	uint32_t num_containers;
6144c28dbdSSrinivas Kandagatla 	struct apm_container_obj cont_obj[];
6244c28dbdSSrinivas Kandagatla } __packed;
6344c28dbdSSrinivas Kandagatla 
6444c28dbdSSrinivas Kandagatla #define APM_CONTAINER_PSIZE(p, n) ALIGN(struct_size(p, cont_obj, n), 8)
6544c28dbdSSrinivas Kandagatla 
6644c28dbdSSrinivas Kandagatla /* Module List config */
6744c28dbdSSrinivas Kandagatla struct apm_mod_list_obj {
6844c28dbdSSrinivas Kandagatla 	/* Modules list cfg */
6944c28dbdSSrinivas Kandagatla 	uint32_t sub_graph_id;
7044c28dbdSSrinivas Kandagatla 	uint32_t container_id;
7144c28dbdSSrinivas Kandagatla 	uint32_t num_modules;
7244c28dbdSSrinivas Kandagatla 	struct apm_module_obj mod_cfg[];
7344c28dbdSSrinivas Kandagatla } __packed;
7444c28dbdSSrinivas Kandagatla 
7544c28dbdSSrinivas Kandagatla #define APM_MOD_LIST_OBJ_PSIZE(p, n) struct_size(p, mod_cfg, n)
7644c28dbdSSrinivas Kandagatla 
7744c28dbdSSrinivas Kandagatla struct apm_module_list_params {
7844c28dbdSSrinivas Kandagatla 	struct apm_module_param_data param_data;
7944c28dbdSSrinivas Kandagatla 	uint32_t num_modules_list;
8044c28dbdSSrinivas Kandagatla 	/* Module list config array */
8144c28dbdSSrinivas Kandagatla 	struct apm_mod_list_obj mod_list_obj[];
8244c28dbdSSrinivas Kandagatla } __packed;
8344c28dbdSSrinivas Kandagatla 
8444c28dbdSSrinivas Kandagatla 
8544c28dbdSSrinivas Kandagatla /* Module Properties */
8644c28dbdSSrinivas Kandagatla struct apm_mod_prop_obj {
8744c28dbdSSrinivas Kandagatla 	u32 instance_id;
8844c28dbdSSrinivas Kandagatla 	u32 num_props;
8944c28dbdSSrinivas Kandagatla 	struct apm_prop_data prop_data_1;
9044c28dbdSSrinivas Kandagatla 	struct apm_module_prop_id_port_info prop_id_port;
9144c28dbdSSrinivas Kandagatla } __packed;
9244c28dbdSSrinivas Kandagatla 
9344c28dbdSSrinivas Kandagatla struct apm_prop_list_params {
9444c28dbdSSrinivas Kandagatla 	struct apm_module_param_data param_data;
9544c28dbdSSrinivas Kandagatla 	u32 num_modules_prop_cfg;
9644c28dbdSSrinivas Kandagatla 	struct apm_mod_prop_obj mod_prop_obj[];
9744c28dbdSSrinivas Kandagatla 
9844c28dbdSSrinivas Kandagatla } __packed;
9944c28dbdSSrinivas Kandagatla 
10044c28dbdSSrinivas Kandagatla #define APM_MOD_PROP_PSIZE(p, n) ALIGN(struct_size(p, mod_prop_obj, n), 8)
10144c28dbdSSrinivas Kandagatla 
10244c28dbdSSrinivas Kandagatla /* Module Connections */
10344c28dbdSSrinivas Kandagatla struct apm_mod_conn_list_params {
10444c28dbdSSrinivas Kandagatla 	struct apm_module_param_data param_data;
10544c28dbdSSrinivas Kandagatla 	u32 num_connections;
10644c28dbdSSrinivas Kandagatla 	struct apm_module_conn_obj conn_obj[];
10744c28dbdSSrinivas Kandagatla 
10844c28dbdSSrinivas Kandagatla } __packed;
10944c28dbdSSrinivas Kandagatla 
11044c28dbdSSrinivas Kandagatla #define APM_MOD_CONN_PSIZE(p, n) ALIGN(struct_size(p, conn_obj, n), 8)
11144c28dbdSSrinivas Kandagatla 
11244c28dbdSSrinivas Kandagatla struct apm_graph_open_params {
11344c28dbdSSrinivas Kandagatla 	struct apm_cmd_header *cmd_header;
11444c28dbdSSrinivas Kandagatla 	struct apm_sub_graph_params *sg_data;
11544c28dbdSSrinivas Kandagatla 	struct apm_container_params *cont_data;
11644c28dbdSSrinivas Kandagatla 	struct apm_module_list_params *mod_list_data;
11744c28dbdSSrinivas Kandagatla 	struct apm_prop_list_params *mod_prop_data;
11844c28dbdSSrinivas Kandagatla 	struct apm_mod_conn_list_params *mod_conn_list_data;
11944c28dbdSSrinivas Kandagatla } __packed;
12044c28dbdSSrinivas Kandagatla 
12144c28dbdSSrinivas Kandagatla struct apm_pcm_module_media_fmt_cmd {
12244c28dbdSSrinivas Kandagatla 	struct apm_module_param_data param_data;
12344c28dbdSSrinivas Kandagatla 	struct param_id_pcm_output_format_cfg header;
12444c28dbdSSrinivas Kandagatla 	struct payload_pcm_output_format_cfg media_cfg;
12544c28dbdSSrinivas Kandagatla } __packed;
12644c28dbdSSrinivas Kandagatla 
12744c28dbdSSrinivas Kandagatla struct apm_rd_shmem_module_config_cmd {
12844c28dbdSSrinivas Kandagatla 	struct apm_module_param_data param_data;
12944c28dbdSSrinivas Kandagatla 	struct param_id_rd_sh_mem_cfg cfg;
13044c28dbdSSrinivas Kandagatla } __packed;
13144c28dbdSSrinivas Kandagatla 
13244c28dbdSSrinivas Kandagatla struct apm_sh_module_media_fmt_cmd {
13344c28dbdSSrinivas Kandagatla 	struct media_format header;
13444c28dbdSSrinivas Kandagatla 	struct payload_media_fmt_pcm cfg;
13544c28dbdSSrinivas Kandagatla } __packed;
13644c28dbdSSrinivas Kandagatla 
13744c28dbdSSrinivas Kandagatla #define APM_SHMEM_FMT_CFG_PSIZE(ch) ALIGN( \
13844c28dbdSSrinivas Kandagatla 				sizeof(struct apm_sh_module_media_fmt_cmd) + \
13944c28dbdSSrinivas Kandagatla 				ch * sizeof(uint8_t), 8)
14044c28dbdSSrinivas Kandagatla 
14144c28dbdSSrinivas Kandagatla /* num of channels as argument */
14244c28dbdSSrinivas Kandagatla #define APM_PCM_MODULE_FMT_CMD_PSIZE(ch) ALIGN( \
14344c28dbdSSrinivas Kandagatla 				sizeof(struct apm_pcm_module_media_fmt_cmd) + \
14444c28dbdSSrinivas Kandagatla 				ch * sizeof(uint8_t), 8)
14544c28dbdSSrinivas Kandagatla 
14644c28dbdSSrinivas Kandagatla #define APM_PCM_OUT_FMT_CFG_PSIZE(p, n) ALIGN(struct_size(p, channel_mapping, n), 4)
14744c28dbdSSrinivas Kandagatla 
14844c28dbdSSrinivas Kandagatla struct apm_i2s_module_intf_cfg {
14944c28dbdSSrinivas Kandagatla 	struct apm_module_param_data param_data;
15044c28dbdSSrinivas Kandagatla 	struct param_id_i2s_intf_cfg cfg;
15144c28dbdSSrinivas Kandagatla } __packed;
15244c28dbdSSrinivas Kandagatla 
15344c28dbdSSrinivas Kandagatla #define APM_I2S_INTF_CFG_PSIZE ALIGN(sizeof(struct apm_i2s_module_intf_cfg), 8)
15444c28dbdSSrinivas Kandagatla 
15544c28dbdSSrinivas Kandagatla struct apm_module_hw_ep_mf_cfg {
15644c28dbdSSrinivas Kandagatla 	struct apm_module_param_data param_data;
15744c28dbdSSrinivas Kandagatla 	struct param_id_hw_ep_mf mf;
15844c28dbdSSrinivas Kandagatla } __packed;
15944c28dbdSSrinivas Kandagatla 
16044c28dbdSSrinivas Kandagatla #define APM_HW_EP_CFG_PSIZE ALIGN(sizeof(struct apm_module_hw_ep_mf_cfg), 8)
16144c28dbdSSrinivas Kandagatla 
162cf0de67dSSrinivas Kandagatla #define APM_MFC_CFG_PSIZE(p, n) ALIGN(struct_size(p, channel_mapping, n), 4)
163cf0de67dSSrinivas Kandagatla 
16444c28dbdSSrinivas Kandagatla struct apm_module_frame_size_factor_cfg {
16544c28dbdSSrinivas Kandagatla 	struct apm_module_param_data param_data;
16644c28dbdSSrinivas Kandagatla 	uint32_t frame_size_factor;
16744c28dbdSSrinivas Kandagatla } __packed;
16844c28dbdSSrinivas Kandagatla 
16944c28dbdSSrinivas Kandagatla #define APM_FS_CFG_PSIZE ALIGN(sizeof(struct apm_module_frame_size_factor_cfg), 8)
17044c28dbdSSrinivas Kandagatla 
17144c28dbdSSrinivas Kandagatla struct apm_module_hw_ep_power_mode_cfg {
17244c28dbdSSrinivas Kandagatla 	struct apm_module_param_data param_data;
17344c28dbdSSrinivas Kandagatla 	struct param_id_hw_ep_power_mode_cfg power_mode;
17444c28dbdSSrinivas Kandagatla } __packed;
17544c28dbdSSrinivas Kandagatla 
17644c28dbdSSrinivas Kandagatla #define APM_HW_EP_PMODE_CFG_PSIZE ALIGN(sizeof(struct apm_module_hw_ep_power_mode_cfg),	8)
17744c28dbdSSrinivas Kandagatla 
17844c28dbdSSrinivas Kandagatla struct apm_module_hw_ep_dma_data_align_cfg {
17944c28dbdSSrinivas Kandagatla 	struct apm_module_param_data param_data;
18044c28dbdSSrinivas Kandagatla 	struct param_id_hw_ep_dma_data_align align;
18144c28dbdSSrinivas Kandagatla } __packed;
18244c28dbdSSrinivas Kandagatla 
18344c28dbdSSrinivas Kandagatla #define APM_HW_EP_DALIGN_CFG_PSIZE ALIGN(sizeof(struct apm_module_hw_ep_dma_data_align_cfg), 8)
18444c28dbdSSrinivas Kandagatla 
18544c28dbdSSrinivas Kandagatla struct apm_gain_module_cfg {
18644c28dbdSSrinivas Kandagatla 	struct apm_module_param_data param_data;
18744c28dbdSSrinivas Kandagatla 	struct param_id_gain_cfg gain_cfg;
18844c28dbdSSrinivas Kandagatla } __packed;
18944c28dbdSSrinivas Kandagatla 
19044c28dbdSSrinivas Kandagatla #define APM_GAIN_CFG_PSIZE ALIGN(sizeof(struct apm_gain_module_cfg), 8)
19144c28dbdSSrinivas Kandagatla 
19244c28dbdSSrinivas Kandagatla struct apm_codec_dma_module_intf_cfg {
19344c28dbdSSrinivas Kandagatla 	struct apm_module_param_data param_data;
19444c28dbdSSrinivas Kandagatla 	struct param_id_codec_dma_intf_cfg cfg;
19544c28dbdSSrinivas Kandagatla } __packed;
19644c28dbdSSrinivas Kandagatla 
19744c28dbdSSrinivas Kandagatla #define APM_CDMA_INTF_CFG_PSIZE ALIGN(sizeof(struct apm_codec_dma_module_intf_cfg), 8)
19844c28dbdSSrinivas Kandagatla 
199a8ab6541SSrinivas Kandagatla struct apm_display_port_module_intf_cfg {
200a8ab6541SSrinivas Kandagatla 	struct apm_module_param_data param_data;
201a8ab6541SSrinivas Kandagatla 	struct param_id_display_port_intf_cfg cfg;
202a8ab6541SSrinivas Kandagatla } __packed;
203a8ab6541SSrinivas Kandagatla #define APM_DP_INTF_CFG_PSIZE ALIGN(sizeof(struct apm_display_port_module_intf_cfg), 8)
204a8ab6541SSrinivas Kandagatla 
__audioreach_alloc_pkt(int payload_size,uint32_t opcode,uint32_t token,uint32_t src_port,uint32_t dest_port,bool has_cmd_hdr)20544c28dbdSSrinivas Kandagatla static void *__audioreach_alloc_pkt(int payload_size, uint32_t opcode, uint32_t token,
20644c28dbdSSrinivas Kandagatla 				    uint32_t src_port, uint32_t dest_port, bool has_cmd_hdr)
20744c28dbdSSrinivas Kandagatla {
20844c28dbdSSrinivas Kandagatla 	struct gpr_pkt *pkt;
20944c28dbdSSrinivas Kandagatla 	void *p;
21044c28dbdSSrinivas Kandagatla 	int pkt_size = GPR_HDR_SIZE + payload_size;
21144c28dbdSSrinivas Kandagatla 
21244c28dbdSSrinivas Kandagatla 	if (has_cmd_hdr)
21344c28dbdSSrinivas Kandagatla 		pkt_size += APM_CMD_HDR_SIZE;
21444c28dbdSSrinivas Kandagatla 
21544c28dbdSSrinivas Kandagatla 	p = kzalloc(pkt_size, GFP_KERNEL);
21644c28dbdSSrinivas Kandagatla 	if (!p)
21744c28dbdSSrinivas Kandagatla 		return ERR_PTR(-ENOMEM);
21844c28dbdSSrinivas Kandagatla 
21944c28dbdSSrinivas Kandagatla 	pkt = p;
22044c28dbdSSrinivas Kandagatla 	pkt->hdr.version = GPR_PKT_VER;
22144c28dbdSSrinivas Kandagatla 	pkt->hdr.hdr_size = GPR_PKT_HEADER_WORD_SIZE;
22244c28dbdSSrinivas Kandagatla 	pkt->hdr.pkt_size = pkt_size;
22344c28dbdSSrinivas Kandagatla 	pkt->hdr.dest_port = dest_port;
22444c28dbdSSrinivas Kandagatla 	pkt->hdr.src_port = src_port;
22544c28dbdSSrinivas Kandagatla 
22644c28dbdSSrinivas Kandagatla 	pkt->hdr.dest_domain = GPR_DOMAIN_ID_ADSP;
22744c28dbdSSrinivas Kandagatla 	pkt->hdr.src_domain = GPR_DOMAIN_ID_APPS;
22844c28dbdSSrinivas Kandagatla 	pkt->hdr.token = token;
22944c28dbdSSrinivas Kandagatla 	pkt->hdr.opcode = opcode;
23044c28dbdSSrinivas Kandagatla 
23144c28dbdSSrinivas Kandagatla 	if (has_cmd_hdr) {
23244c28dbdSSrinivas Kandagatla 		struct apm_cmd_header *cmd_header;
23344c28dbdSSrinivas Kandagatla 
23444c28dbdSSrinivas Kandagatla 		p = p + GPR_HDR_SIZE;
23544c28dbdSSrinivas Kandagatla 		cmd_header = p;
23644c28dbdSSrinivas Kandagatla 		cmd_header->payload_size = payload_size;
23744c28dbdSSrinivas Kandagatla 	}
23844c28dbdSSrinivas Kandagatla 
23944c28dbdSSrinivas Kandagatla 	return pkt;
24044c28dbdSSrinivas Kandagatla }
24144c28dbdSSrinivas Kandagatla 
audioreach_alloc_pkt(int payload_size,uint32_t opcode,uint32_t token,uint32_t src_port,uint32_t dest_port)24244c28dbdSSrinivas Kandagatla void *audioreach_alloc_pkt(int payload_size, uint32_t opcode, uint32_t token,
24344c28dbdSSrinivas Kandagatla 			   uint32_t src_port, uint32_t dest_port)
24444c28dbdSSrinivas Kandagatla {
24544c28dbdSSrinivas Kandagatla 	return __audioreach_alloc_pkt(payload_size, opcode, token, src_port, dest_port, false);
24644c28dbdSSrinivas Kandagatla }
24744c28dbdSSrinivas Kandagatla EXPORT_SYMBOL_GPL(audioreach_alloc_pkt);
24844c28dbdSSrinivas Kandagatla 
audioreach_alloc_apm_pkt(int pkt_size,uint32_t opcode,uint32_t token,uint32_t src_port)24944c28dbdSSrinivas Kandagatla void *audioreach_alloc_apm_pkt(int pkt_size, uint32_t opcode, uint32_t token, uint32_t src_port)
25044c28dbdSSrinivas Kandagatla {
25144c28dbdSSrinivas Kandagatla 	return __audioreach_alloc_pkt(pkt_size, opcode, token, src_port, APM_MODULE_INSTANCE_ID,
25244c28dbdSSrinivas Kandagatla 				      false);
25344c28dbdSSrinivas Kandagatla }
25444c28dbdSSrinivas Kandagatla EXPORT_SYMBOL_GPL(audioreach_alloc_apm_pkt);
25544c28dbdSSrinivas Kandagatla 
audioreach_alloc_cmd_pkt(int payload_size,uint32_t opcode,uint32_t token,uint32_t src_port,uint32_t dest_port)25644c28dbdSSrinivas Kandagatla void *audioreach_alloc_cmd_pkt(int payload_size, uint32_t opcode, uint32_t token,
25744c28dbdSSrinivas Kandagatla 			       uint32_t src_port, uint32_t dest_port)
25844c28dbdSSrinivas Kandagatla {
25944c28dbdSSrinivas Kandagatla 	return __audioreach_alloc_pkt(payload_size, opcode, token, src_port, dest_port, true);
26044c28dbdSSrinivas Kandagatla }
26144c28dbdSSrinivas Kandagatla EXPORT_SYMBOL_GPL(audioreach_alloc_cmd_pkt);
26244c28dbdSSrinivas Kandagatla 
audioreach_alloc_apm_cmd_pkt(int pkt_size,uint32_t opcode,uint32_t token)26344c28dbdSSrinivas Kandagatla void *audioreach_alloc_apm_cmd_pkt(int pkt_size, uint32_t opcode, uint32_t token)
26444c28dbdSSrinivas Kandagatla {
26544c28dbdSSrinivas Kandagatla 	return __audioreach_alloc_pkt(pkt_size, opcode, token, GPR_APM_MODULE_IID,
26644c28dbdSSrinivas Kandagatla 				       APM_MODULE_INSTANCE_ID, true);
26744c28dbdSSrinivas Kandagatla }
26844c28dbdSSrinivas Kandagatla EXPORT_SYMBOL_GPL(audioreach_alloc_apm_cmd_pkt);
2695477518bSSrinivas Kandagatla 
apm_populate_container_config(struct apm_container_obj * cfg,struct audioreach_container * cont)2705477518bSSrinivas Kandagatla static void apm_populate_container_config(struct apm_container_obj *cfg,
2715477518bSSrinivas Kandagatla 					  struct audioreach_container *cont)
2725477518bSSrinivas Kandagatla {
2735477518bSSrinivas Kandagatla 
2745477518bSSrinivas Kandagatla 	/* Container Config */
2755477518bSSrinivas Kandagatla 	cfg->container_cfg.container_id = cont->container_id;
2765477518bSSrinivas Kandagatla 	cfg->container_cfg.num_prop = 4;
2775477518bSSrinivas Kandagatla 
2785477518bSSrinivas Kandagatla 	/* Capability list */
2795477518bSSrinivas Kandagatla 	cfg->cap_data.prop_id = APM_CONTAINER_PROP_ID_CAPABILITY_LIST;
2805477518bSSrinivas Kandagatla 	cfg->cap_data.prop_size = APM_CONTAINER_PROP_ID_CAPABILITY_SIZE;
2815477518bSSrinivas Kandagatla 	cfg->num_capability_id = 1;
2825477518bSSrinivas Kandagatla 	cfg->capability_id = cont->capability_id;
2835477518bSSrinivas Kandagatla 
2845477518bSSrinivas Kandagatla 	/* Graph Position */
2855477518bSSrinivas Kandagatla 	cfg->pos_data.prop_id = APM_CONTAINER_PROP_ID_GRAPH_POS;
2865477518bSSrinivas Kandagatla 	cfg->pos_data.prop_size = sizeof(struct apm_cont_prop_id_graph_pos);
2875477518bSSrinivas Kandagatla 	cfg->pos.graph_pos = cont->graph_pos;
2885477518bSSrinivas Kandagatla 
2895477518bSSrinivas Kandagatla 	/* Stack size */
2905477518bSSrinivas Kandagatla 	cfg->stack_data.prop_id = APM_CONTAINER_PROP_ID_STACK_SIZE;
2915477518bSSrinivas Kandagatla 	cfg->stack_data.prop_size = sizeof(struct apm_cont_prop_id_stack_size);
2925477518bSSrinivas Kandagatla 	cfg->stack.stack_size = cont->stack_size;
2935477518bSSrinivas Kandagatla 
2945477518bSSrinivas Kandagatla 	/* Proc domain */
2955477518bSSrinivas Kandagatla 	cfg->domain_data.prop_id = APM_CONTAINER_PROP_ID_PROC_DOMAIN;
2965477518bSSrinivas Kandagatla 	cfg->domain_data.prop_size = sizeof(struct apm_cont_prop_id_domain);
2975477518bSSrinivas Kandagatla 	cfg->domain.proc_domain = cont->proc_domain;
2985477518bSSrinivas Kandagatla }
2995477518bSSrinivas Kandagatla 
apm_populate_sub_graph_config(struct apm_sub_graph_data * cfg,struct audioreach_sub_graph * sg)3005477518bSSrinivas Kandagatla static void apm_populate_sub_graph_config(struct apm_sub_graph_data *cfg,
3015477518bSSrinivas Kandagatla 					  struct audioreach_sub_graph *sg)
3025477518bSSrinivas Kandagatla {
3035477518bSSrinivas Kandagatla 	cfg->sub_graph_cfg.sub_graph_id = sg->sub_graph_id;
3045477518bSSrinivas Kandagatla 	cfg->sub_graph_cfg.num_sub_graph_prop = APM_SUB_GRAPH_CFG_NPROP;
3055477518bSSrinivas Kandagatla 
3065477518bSSrinivas Kandagatla 	/* Perf Mode */
3075477518bSSrinivas Kandagatla 	cfg->perf_data.prop_id = APM_SUB_GRAPH_PROP_ID_PERF_MODE;
3085477518bSSrinivas Kandagatla 	cfg->perf_data.prop_size = APM_SG_PROP_ID_PERF_MODE_SIZE;
3095477518bSSrinivas Kandagatla 	cfg->perf.perf_mode = sg->perf_mode;
3105477518bSSrinivas Kandagatla 
3115477518bSSrinivas Kandagatla 	/* Direction */
3125477518bSSrinivas Kandagatla 	cfg->dir_data.prop_id = APM_SUB_GRAPH_PROP_ID_DIRECTION;
3135477518bSSrinivas Kandagatla 	cfg->dir_data.prop_size = APM_SG_PROP_ID_DIR_SIZE;
3145477518bSSrinivas Kandagatla 	cfg->dir.direction = sg->direction;
3155477518bSSrinivas Kandagatla 
3165477518bSSrinivas Kandagatla 	/* Scenario ID */
3175477518bSSrinivas Kandagatla 	cfg->sid_data.prop_id = APM_SUB_GRAPH_PROP_ID_SCENARIO_ID;
3185477518bSSrinivas Kandagatla 	cfg->sid_data.prop_size = APM_SG_PROP_ID_SID_SIZE;
3195477518bSSrinivas Kandagatla 	cfg->sid.scenario_id = sg->scenario_id;
3205477518bSSrinivas Kandagatla }
3215477518bSSrinivas Kandagatla 
apm_populate_module_prop_obj(struct apm_mod_prop_obj * obj,struct audioreach_module * module)3225477518bSSrinivas Kandagatla static void apm_populate_module_prop_obj(struct apm_mod_prop_obj *obj,
3235477518bSSrinivas Kandagatla 					 struct audioreach_module *module)
3245477518bSSrinivas Kandagatla {
3255477518bSSrinivas Kandagatla 
3265477518bSSrinivas Kandagatla 	obj->instance_id = module->instance_id;
3275477518bSSrinivas Kandagatla 	obj->num_props = 1;
3285477518bSSrinivas Kandagatla 	obj->prop_data_1.prop_id = APM_MODULE_PROP_ID_PORT_INFO;
3295477518bSSrinivas Kandagatla 	obj->prop_data_1.prop_size = APM_MODULE_PROP_ID_PORT_INFO_SZ;
3305477518bSSrinivas Kandagatla 	obj->prop_id_port.max_ip_port = module->max_ip_port;
3315477518bSSrinivas Kandagatla 	obj->prop_id_port.max_op_port = module->max_op_port;
3325477518bSSrinivas Kandagatla }
3335477518bSSrinivas Kandagatla 
apm_populate_module_list_obj(struct apm_mod_list_obj * obj,struct audioreach_container * container,int sub_graph_id)3345477518bSSrinivas Kandagatla static void apm_populate_module_list_obj(struct apm_mod_list_obj *obj,
3355477518bSSrinivas Kandagatla 					 struct audioreach_container *container,
3365477518bSSrinivas Kandagatla 					 int sub_graph_id)
3375477518bSSrinivas Kandagatla {
3385477518bSSrinivas Kandagatla 	struct audioreach_module *module;
3395477518bSSrinivas Kandagatla 	int i;
3405477518bSSrinivas Kandagatla 
3415477518bSSrinivas Kandagatla 	obj->sub_graph_id = sub_graph_id;
3425477518bSSrinivas Kandagatla 	obj->container_id = container->container_id;
3435477518bSSrinivas Kandagatla 	obj->num_modules = container->num_modules;
3445477518bSSrinivas Kandagatla 	i = 0;
345e4977b91SSrinivas Kandagatla 	list_for_each_entry(module, &container->modules_list, node) {
3465477518bSSrinivas Kandagatla 		obj->mod_cfg[i].module_id = module->module_id;
3475477518bSSrinivas Kandagatla 		obj->mod_cfg[i].instance_id = module->instance_id;
3485477518bSSrinivas Kandagatla 		i++;
3495477518bSSrinivas Kandagatla 	}
3505477518bSSrinivas Kandagatla }
3515477518bSSrinivas Kandagatla 
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)352e4977b91SSrinivas Kandagatla static void audioreach_populate_graph(struct q6apm *apm, struct audioreach_graph_info *info,
353e4977b91SSrinivas Kandagatla 				      struct apm_graph_open_params *open,
3545477518bSSrinivas Kandagatla 				      struct list_head *sg_list,
3555477518bSSrinivas Kandagatla 				      int num_sub_graphs)
3565477518bSSrinivas Kandagatla {
3575477518bSSrinivas Kandagatla 	struct apm_mod_conn_list_params *mc_data = open->mod_conn_list_data;
3585477518bSSrinivas Kandagatla 	struct apm_module_list_params *ml_data = open->mod_list_data;
3595477518bSSrinivas Kandagatla 	struct apm_prop_list_params *mp_data = open->mod_prop_data;
3605477518bSSrinivas Kandagatla 	struct apm_container_params *c_data = open->cont_data;
3615477518bSSrinivas Kandagatla 	struct apm_sub_graph_params *sg_data = open->sg_data;
3625477518bSSrinivas Kandagatla 	int ncontainer = 0, nmodule = 0, nconn = 0;
3635477518bSSrinivas Kandagatla 	struct apm_mod_prop_obj *module_prop_obj;
3645477518bSSrinivas Kandagatla 	struct audioreach_container *container;
3655477518bSSrinivas Kandagatla 	struct apm_module_conn_obj *conn_obj;
3665477518bSSrinivas Kandagatla 	struct audioreach_module *module;
3675477518bSSrinivas Kandagatla 	struct audioreach_sub_graph *sg;
3685477518bSSrinivas Kandagatla 	struct apm_container_obj *cobj;
3695477518bSSrinivas Kandagatla 	struct apm_mod_list_obj *mlobj;
3705477518bSSrinivas Kandagatla 	int i = 0;
3715477518bSSrinivas Kandagatla 
3725477518bSSrinivas Kandagatla 	mlobj = &ml_data->mod_list_obj[0];
3735477518bSSrinivas Kandagatla 
374e4977b91SSrinivas Kandagatla 
375e4977b91SSrinivas Kandagatla 	if (info->dst_mod_inst_id && info->src_mod_inst_id) {
376e4977b91SSrinivas Kandagatla 		conn_obj = &mc_data->conn_obj[nconn];
377e4977b91SSrinivas Kandagatla 		conn_obj->src_mod_inst_id = info->src_mod_inst_id;
378e4977b91SSrinivas Kandagatla 		conn_obj->src_mod_op_port_id = info->src_mod_op_port_id;
379e4977b91SSrinivas Kandagatla 		conn_obj->dst_mod_inst_id = info->dst_mod_inst_id;
380e4977b91SSrinivas Kandagatla 		conn_obj->dst_mod_ip_port_id = info->dst_mod_ip_port_id;
381e4977b91SSrinivas Kandagatla 		nconn++;
382e4977b91SSrinivas Kandagatla 	}
383e4977b91SSrinivas Kandagatla 
3845477518bSSrinivas Kandagatla 	list_for_each_entry(sg, sg_list, node) {
3855477518bSSrinivas Kandagatla 		struct apm_sub_graph_data *sg_cfg = &sg_data->sg_cfg[i++];
3865477518bSSrinivas Kandagatla 
3875477518bSSrinivas Kandagatla 		apm_populate_sub_graph_config(sg_cfg, sg);
3885477518bSSrinivas Kandagatla 
3895477518bSSrinivas Kandagatla 		list_for_each_entry(container, &sg->container_list, node) {
3905477518bSSrinivas Kandagatla 			cobj = &c_data->cont_obj[ncontainer];
3915477518bSSrinivas Kandagatla 
3925477518bSSrinivas Kandagatla 			apm_populate_container_config(cobj, container);
3935477518bSSrinivas Kandagatla 			apm_populate_module_list_obj(mlobj, container, sg->sub_graph_id);
3945477518bSSrinivas Kandagatla 
395e4977b91SSrinivas Kandagatla 			list_for_each_entry(module, &container->modules_list, node) {
39603365d6aSSrinivas Kandagatla 				int pn;
3975477518bSSrinivas Kandagatla 
39803365d6aSSrinivas Kandagatla 				module_prop_obj = &mp_data->mod_prop_obj[nmodule++];
3995477518bSSrinivas Kandagatla 				apm_populate_module_prop_obj(module_prop_obj, module);
4005477518bSSrinivas Kandagatla 
40103365d6aSSrinivas Kandagatla 				if (!module->max_op_port)
40203365d6aSSrinivas Kandagatla 					continue;
40303365d6aSSrinivas Kandagatla 
40403365d6aSSrinivas Kandagatla 				for (pn = 0; pn < module->max_op_port; pn++) {
40503365d6aSSrinivas Kandagatla 					if (module->dst_mod_inst_id[pn]) {
4065477518bSSrinivas Kandagatla 						conn_obj = &mc_data->conn_obj[nconn];
40703365d6aSSrinivas Kandagatla 						conn_obj->src_mod_inst_id = module->instance_id;
40803365d6aSSrinivas Kandagatla 						conn_obj->src_mod_op_port_id =
40903365d6aSSrinivas Kandagatla 								module->src_mod_op_port_id[pn];
41003365d6aSSrinivas Kandagatla 						conn_obj->dst_mod_inst_id =
41103365d6aSSrinivas Kandagatla 								module->dst_mod_inst_id[pn];
41203365d6aSSrinivas Kandagatla 						conn_obj->dst_mod_ip_port_id =
41303365d6aSSrinivas Kandagatla 								module->dst_mod_ip_port_id[pn];
4145477518bSSrinivas Kandagatla 						nconn++;
4155477518bSSrinivas Kandagatla 					}
4165477518bSSrinivas Kandagatla 				}
41703365d6aSSrinivas Kandagatla 			}
41803365d6aSSrinivas Kandagatla 			mlobj = (void *) mlobj + APM_MOD_LIST_OBJ_PSIZE(mlobj,
41903365d6aSSrinivas Kandagatla 									container->num_modules);
4205477518bSSrinivas Kandagatla 
4215477518bSSrinivas Kandagatla 			ncontainer++;
4225477518bSSrinivas Kandagatla 		}
4235477518bSSrinivas Kandagatla 	}
4245477518bSSrinivas Kandagatla }
4255477518bSSrinivas Kandagatla 
audioreach_alloc_graph_pkt(struct q6apm * apm,struct audioreach_graph_info * info)426e4977b91SSrinivas Kandagatla void *audioreach_alloc_graph_pkt(struct q6apm *apm, struct audioreach_graph_info *info)
4275477518bSSrinivas Kandagatla {
4285477518bSSrinivas Kandagatla 	int payload_size, sg_sz, cont_sz, ml_sz, mp_sz, mc_sz;
4295477518bSSrinivas Kandagatla 	struct apm_module_param_data  *param_data;
4305477518bSSrinivas Kandagatla 	struct apm_container_params *cont_params;
4315477518bSSrinivas Kandagatla 	struct audioreach_container *container;
4325477518bSSrinivas Kandagatla 	struct apm_sub_graph_params *sg_params;
4335477518bSSrinivas Kandagatla 	struct apm_mod_conn_list_params *mcon;
4345477518bSSrinivas Kandagatla 	struct apm_graph_open_params params;
4355477518bSSrinivas Kandagatla 	struct apm_prop_list_params *mprop;
4365477518bSSrinivas Kandagatla 	struct audioreach_module *module;
4375477518bSSrinivas Kandagatla 	struct audioreach_sub_graph *sgs;
4385477518bSSrinivas Kandagatla 	struct apm_mod_list_obj *mlobj;
439e4977b91SSrinivas Kandagatla 	struct list_head *sg_list;
4405477518bSSrinivas Kandagatla 	int num_connections = 0;
4415477518bSSrinivas Kandagatla 	int num_containers = 0;
4425477518bSSrinivas Kandagatla 	int num_sub_graphs = 0;
4435477518bSSrinivas Kandagatla 	int num_modules = 0;
4445477518bSSrinivas Kandagatla 	int num_modules_list;
4455477518bSSrinivas Kandagatla 	struct gpr_pkt *pkt;
4465477518bSSrinivas Kandagatla 	void *p;
4475477518bSSrinivas Kandagatla 
448e4977b91SSrinivas Kandagatla 	sg_list = &info->sg_list;
449e4977b91SSrinivas Kandagatla 	ml_sz = 0;
450e4977b91SSrinivas Kandagatla 
451e4977b91SSrinivas Kandagatla 	/* add FE-BE connections */
452e4977b91SSrinivas Kandagatla 	if (info->dst_mod_inst_id && info->src_mod_inst_id)
453e4977b91SSrinivas Kandagatla 		num_connections++;
454e4977b91SSrinivas Kandagatla 
4555477518bSSrinivas Kandagatla 	list_for_each_entry(sgs, sg_list, node) {
4565477518bSSrinivas Kandagatla 		num_sub_graphs++;
4575477518bSSrinivas Kandagatla 		list_for_each_entry(container, &sgs->container_list, node) {
4585477518bSSrinivas Kandagatla 			num_containers++;
4595477518bSSrinivas Kandagatla 			num_modules += container->num_modules;
4604efb98e9SSrinivas Kandagatla 			ml_sz = ml_sz + sizeof(struct apm_module_list_params) +
4614efb98e9SSrinivas Kandagatla 				APM_MOD_LIST_OBJ_PSIZE(mlobj, container->num_modules);
4624efb98e9SSrinivas Kandagatla 
463e4977b91SSrinivas Kandagatla 			list_for_each_entry(module, &container->modules_list, node) {
46403365d6aSSrinivas Kandagatla 				num_connections += module->num_connections;
4655477518bSSrinivas Kandagatla 			}
4665477518bSSrinivas Kandagatla 		}
4675477518bSSrinivas Kandagatla 	}
4685477518bSSrinivas Kandagatla 
4695477518bSSrinivas Kandagatla 	num_modules_list = num_containers;
4705477518bSSrinivas Kandagatla 	sg_sz = APM_SUB_GRAPH_PSIZE(sg_params, num_sub_graphs);
4715477518bSSrinivas Kandagatla 	cont_sz = APM_CONTAINER_PSIZE(cont_params, num_containers);
4724efb98e9SSrinivas Kandagatla 
4734efb98e9SSrinivas Kandagatla 	ml_sz = ALIGN(ml_sz, 8);
4744efb98e9SSrinivas Kandagatla 
4755477518bSSrinivas Kandagatla 	mp_sz = APM_MOD_PROP_PSIZE(mprop, num_modules);
4765477518bSSrinivas Kandagatla 	mc_sz =	APM_MOD_CONN_PSIZE(mcon, num_connections);
4775477518bSSrinivas Kandagatla 
4785477518bSSrinivas Kandagatla 	payload_size = sg_sz + cont_sz + ml_sz + mp_sz + mc_sz;
4795477518bSSrinivas Kandagatla 	pkt = audioreach_alloc_apm_cmd_pkt(payload_size, APM_CMD_GRAPH_OPEN, 0);
4805477518bSSrinivas Kandagatla 	if (IS_ERR(pkt))
4815477518bSSrinivas Kandagatla 		return pkt;
4825477518bSSrinivas Kandagatla 
4835477518bSSrinivas Kandagatla 	p = (void *)pkt + GPR_HDR_SIZE + APM_CMD_HDR_SIZE;
4845477518bSSrinivas Kandagatla 
4855477518bSSrinivas Kandagatla 	/* SubGraph */
4865477518bSSrinivas Kandagatla 	params.sg_data = p;
4875477518bSSrinivas Kandagatla 	param_data = &params.sg_data->param_data;
4885477518bSSrinivas Kandagatla 	param_data->module_instance_id = APM_MODULE_INSTANCE_ID;
4895477518bSSrinivas Kandagatla 	param_data->param_id = APM_PARAM_ID_SUB_GRAPH_CONFIG;
4905477518bSSrinivas Kandagatla 	param_data->param_size = sg_sz - APM_MODULE_PARAM_DATA_SIZE;
4915477518bSSrinivas Kandagatla 	params.sg_data->num_sub_graphs = num_sub_graphs;
4925477518bSSrinivas Kandagatla 	p += sg_sz;
4935477518bSSrinivas Kandagatla 
4945477518bSSrinivas Kandagatla 	/* Container */
4955477518bSSrinivas Kandagatla 	params.cont_data = p;
4965477518bSSrinivas Kandagatla 	param_data = &params.cont_data->param_data;
4975477518bSSrinivas Kandagatla 	param_data->module_instance_id = APM_MODULE_INSTANCE_ID;
4985477518bSSrinivas Kandagatla 	param_data->param_id = APM_PARAM_ID_CONTAINER_CONFIG;
4995477518bSSrinivas Kandagatla 	param_data->param_size = cont_sz - APM_MODULE_PARAM_DATA_SIZE;
5005477518bSSrinivas Kandagatla 	params.cont_data->num_containers = num_containers;
5015477518bSSrinivas Kandagatla 	p += cont_sz;
5025477518bSSrinivas Kandagatla 
5035477518bSSrinivas Kandagatla 	/* Module List*/
5045477518bSSrinivas Kandagatla 	params.mod_list_data = p;
5055477518bSSrinivas Kandagatla 	param_data = &params.mod_list_data->param_data;
5065477518bSSrinivas Kandagatla 	param_data->module_instance_id = APM_MODULE_INSTANCE_ID;
5075477518bSSrinivas Kandagatla 	param_data->param_id = APM_PARAM_ID_MODULE_LIST;
5085477518bSSrinivas Kandagatla 	param_data->param_size = ml_sz - APM_MODULE_PARAM_DATA_SIZE;
50903365d6aSSrinivas Kandagatla 	params.mod_list_data->num_modules_list = num_modules_list;
5105477518bSSrinivas Kandagatla 	p += ml_sz;
5115477518bSSrinivas Kandagatla 
5125477518bSSrinivas Kandagatla 	/* Module Properties */
5135477518bSSrinivas Kandagatla 	params.mod_prop_data = p;
5145477518bSSrinivas Kandagatla 	param_data = &params.mod_prop_data->param_data;
5155477518bSSrinivas Kandagatla 	param_data->module_instance_id = APM_MODULE_INSTANCE_ID;
5165477518bSSrinivas Kandagatla 	param_data->param_id = APM_PARAM_ID_MODULE_PROP;
5175477518bSSrinivas Kandagatla 	param_data->param_size = mp_sz - APM_MODULE_PARAM_DATA_SIZE;
5185477518bSSrinivas Kandagatla 	params.mod_prop_data->num_modules_prop_cfg = num_modules;
5195477518bSSrinivas Kandagatla 	p += mp_sz;
5205477518bSSrinivas Kandagatla 
5215477518bSSrinivas Kandagatla 	/* Module Connections */
5225477518bSSrinivas Kandagatla 	params.mod_conn_list_data = p;
5235477518bSSrinivas Kandagatla 	param_data = &params.mod_conn_list_data->param_data;
5245477518bSSrinivas Kandagatla 	param_data->module_instance_id = APM_MODULE_INSTANCE_ID;
5255477518bSSrinivas Kandagatla 	param_data->param_id = APM_PARAM_ID_MODULE_CONN;
5265477518bSSrinivas Kandagatla 	param_data->param_size = mc_sz - APM_MODULE_PARAM_DATA_SIZE;
5275477518bSSrinivas Kandagatla 	params.mod_conn_list_data->num_connections = num_connections;
5285477518bSSrinivas Kandagatla 	p += mc_sz;
5295477518bSSrinivas Kandagatla 
530e4977b91SSrinivas Kandagatla 	audioreach_populate_graph(apm, info, &params, sg_list, num_sub_graphs);
5315477518bSSrinivas Kandagatla 
5325477518bSSrinivas Kandagatla 	return pkt;
5335477518bSSrinivas Kandagatla }
5345477518bSSrinivas Kandagatla EXPORT_SYMBOL_GPL(audioreach_alloc_graph_pkt);
53525ab80dbSSrinivas Kandagatla 
audioreach_send_cmd_sync(struct device * dev,gpr_device_t * gdev,struct gpr_ibasic_rsp_result_t * result,struct mutex * cmd_lock,gpr_port_t * port,wait_queue_head_t * cmd_wait,struct gpr_pkt * pkt,uint32_t rsp_opcode)53625ab80dbSSrinivas Kandagatla int audioreach_send_cmd_sync(struct device *dev, gpr_device_t *gdev,
53725ab80dbSSrinivas Kandagatla 			     struct gpr_ibasic_rsp_result_t *result, struct mutex *cmd_lock,
53825ab80dbSSrinivas Kandagatla 			     gpr_port_t *port, wait_queue_head_t *cmd_wait,
53925ab80dbSSrinivas Kandagatla 			     struct gpr_pkt *pkt, uint32_t rsp_opcode)
54025ab80dbSSrinivas Kandagatla {
54125ab80dbSSrinivas Kandagatla 
54225ab80dbSSrinivas Kandagatla 	struct gpr_hdr *hdr = &pkt->hdr;
54325ab80dbSSrinivas Kandagatla 	int rc;
54425ab80dbSSrinivas Kandagatla 
54525ab80dbSSrinivas Kandagatla 	mutex_lock(cmd_lock);
54625ab80dbSSrinivas Kandagatla 	result->opcode = 0;
54725ab80dbSSrinivas Kandagatla 	result->status = 0;
54825ab80dbSSrinivas Kandagatla 
54925ab80dbSSrinivas Kandagatla 	if (port)
55025ab80dbSSrinivas Kandagatla 		rc = gpr_send_port_pkt(port, pkt);
55125ab80dbSSrinivas Kandagatla 	else if (gdev)
55225ab80dbSSrinivas Kandagatla 		rc = gpr_send_pkt(gdev, pkt);
55325ab80dbSSrinivas Kandagatla 	else
55425ab80dbSSrinivas Kandagatla 		rc = -EINVAL;
55525ab80dbSSrinivas Kandagatla 
55625ab80dbSSrinivas Kandagatla 	if (rc < 0)
55725ab80dbSSrinivas Kandagatla 		goto err;
55825ab80dbSSrinivas Kandagatla 
55925ab80dbSSrinivas Kandagatla 	if (rsp_opcode)
56025ab80dbSSrinivas Kandagatla 		rc = wait_event_timeout(*cmd_wait, (result->opcode == hdr->opcode) ||
56125ab80dbSSrinivas Kandagatla 					(result->opcode == rsp_opcode),	5 * HZ);
56225ab80dbSSrinivas Kandagatla 	else
56325ab80dbSSrinivas Kandagatla 		rc = wait_event_timeout(*cmd_wait, (result->opcode == hdr->opcode), 5 * HZ);
56425ab80dbSSrinivas Kandagatla 
56525ab80dbSSrinivas Kandagatla 	if (!rc) {
56625ab80dbSSrinivas Kandagatla 		dev_err(dev, "CMD timeout for [%x] opcode\n", hdr->opcode);
56725ab80dbSSrinivas Kandagatla 		rc = -ETIMEDOUT;
56825ab80dbSSrinivas Kandagatla 	} else if (result->status > 0) {
56925ab80dbSSrinivas Kandagatla 		dev_err(dev, "DSP returned error[%x] %x\n", hdr->opcode, result->status);
57025ab80dbSSrinivas Kandagatla 		rc = -EINVAL;
57125ab80dbSSrinivas Kandagatla 	} else {
57225ab80dbSSrinivas Kandagatla 		/* DSP successfully finished the command */
57325ab80dbSSrinivas Kandagatla 		rc = 0;
57425ab80dbSSrinivas Kandagatla 	}
57525ab80dbSSrinivas Kandagatla 
57625ab80dbSSrinivas Kandagatla err:
57725ab80dbSSrinivas Kandagatla 	mutex_unlock(cmd_lock);
57825ab80dbSSrinivas Kandagatla 	return rc;
57925ab80dbSSrinivas Kandagatla }
58025ab80dbSSrinivas Kandagatla EXPORT_SYMBOL_GPL(audioreach_send_cmd_sync);
58125ab80dbSSrinivas Kandagatla 
audioreach_graph_send_cmd_sync(struct q6apm_graph * graph,struct gpr_pkt * pkt,uint32_t rsp_opcode)58225ab80dbSSrinivas Kandagatla int audioreach_graph_send_cmd_sync(struct q6apm_graph *graph, struct gpr_pkt *pkt,
58325ab80dbSSrinivas Kandagatla 				   uint32_t rsp_opcode)
58425ab80dbSSrinivas Kandagatla {
58525ab80dbSSrinivas Kandagatla 
58625ab80dbSSrinivas Kandagatla 	return audioreach_send_cmd_sync(graph->dev, NULL,  &graph->result, &graph->lock,
58725ab80dbSSrinivas Kandagatla 					graph->port, &graph->cmd_wait, pkt, rsp_opcode);
58825ab80dbSSrinivas Kandagatla }
58925ab80dbSSrinivas Kandagatla EXPORT_SYMBOL_GPL(audioreach_graph_send_cmd_sync);
59025ab80dbSSrinivas Kandagatla 
audioreach_display_port_set_media_format(struct q6apm_graph * graph,struct audioreach_module * module,struct audioreach_module_config * cfg)591a8ab6541SSrinivas Kandagatla static int audioreach_display_port_set_media_format(struct q6apm_graph *graph,
592a8ab6541SSrinivas Kandagatla 						    struct audioreach_module *module,
593a8ab6541SSrinivas Kandagatla 						    struct audioreach_module_config *cfg)
594a8ab6541SSrinivas Kandagatla {
595a8ab6541SSrinivas Kandagatla 	struct apm_display_port_module_intf_cfg *intf_cfg;
596a8ab6541SSrinivas Kandagatla 	struct apm_module_frame_size_factor_cfg *fs_cfg;
597a8ab6541SSrinivas Kandagatla 	struct apm_module_param_data *param_data;
598a8ab6541SSrinivas Kandagatla 	struct apm_module_hw_ep_mf_cfg *hw_cfg;
599a8ab6541SSrinivas Kandagatla 	int ic_sz, ep_sz, fs_sz, dl_sz;
600a8ab6541SSrinivas Kandagatla 	int rc, payload_size;
601a8ab6541SSrinivas Kandagatla 	struct gpr_pkt *pkt;
602a8ab6541SSrinivas Kandagatla 	void *p;
603a8ab6541SSrinivas Kandagatla 
604a8ab6541SSrinivas Kandagatla 	ic_sz = APM_DP_INTF_CFG_PSIZE;
605a8ab6541SSrinivas Kandagatla 	ep_sz = APM_HW_EP_CFG_PSIZE;
606a8ab6541SSrinivas Kandagatla 	fs_sz = APM_FS_CFG_PSIZE;
607a8ab6541SSrinivas Kandagatla 	dl_sz = 0;
608a8ab6541SSrinivas Kandagatla 
609a8ab6541SSrinivas Kandagatla 	payload_size = ic_sz + ep_sz + fs_sz + dl_sz;
610a8ab6541SSrinivas Kandagatla 
611a8ab6541SSrinivas Kandagatla 	pkt = audioreach_alloc_apm_cmd_pkt(payload_size, APM_CMD_SET_CFG, 0);
612a8ab6541SSrinivas Kandagatla 	if (IS_ERR(pkt))
613a8ab6541SSrinivas Kandagatla 		return PTR_ERR(pkt);
614a8ab6541SSrinivas Kandagatla 
615a8ab6541SSrinivas Kandagatla 	p = (void *)pkt + GPR_HDR_SIZE + APM_CMD_HDR_SIZE;
616a8ab6541SSrinivas Kandagatla 
617a8ab6541SSrinivas Kandagatla 	hw_cfg = p;
618a8ab6541SSrinivas Kandagatla 	param_data = &hw_cfg->param_data;
619a8ab6541SSrinivas Kandagatla 	param_data->module_instance_id = module->instance_id;
620a8ab6541SSrinivas Kandagatla 	param_data->error_code = 0;
621a8ab6541SSrinivas Kandagatla 	param_data->param_id = PARAM_ID_HW_EP_MF_CFG;
622a8ab6541SSrinivas Kandagatla 	param_data->param_size = ep_sz - APM_MODULE_PARAM_DATA_SIZE;
623a8ab6541SSrinivas Kandagatla 
624a8ab6541SSrinivas Kandagatla 	hw_cfg->mf.sample_rate = cfg->sample_rate;
625a8ab6541SSrinivas Kandagatla 	hw_cfg->mf.bit_width = cfg->bit_width;
626a8ab6541SSrinivas Kandagatla 	hw_cfg->mf.num_channels = cfg->num_channels;
627a8ab6541SSrinivas Kandagatla 	hw_cfg->mf.data_format = module->data_format;
628a8ab6541SSrinivas Kandagatla 	p += ep_sz;
629a8ab6541SSrinivas Kandagatla 
630a8ab6541SSrinivas Kandagatla 	fs_cfg = p;
631a8ab6541SSrinivas Kandagatla 	param_data = &fs_cfg->param_data;
632a8ab6541SSrinivas Kandagatla 	param_data->module_instance_id = module->instance_id;
633a8ab6541SSrinivas Kandagatla 	param_data->error_code = 0;
634a8ab6541SSrinivas Kandagatla 	param_data->param_id = PARAM_ID_HW_EP_FRAME_SIZE_FACTOR;
635a8ab6541SSrinivas Kandagatla 	param_data->param_size = fs_sz - APM_MODULE_PARAM_DATA_SIZE;
636a8ab6541SSrinivas Kandagatla 	fs_cfg->frame_size_factor = 1;
637a8ab6541SSrinivas Kandagatla 	p += fs_sz;
638a8ab6541SSrinivas Kandagatla 
639a8ab6541SSrinivas Kandagatla 	intf_cfg = p;
640a8ab6541SSrinivas Kandagatla 	param_data = &intf_cfg->param_data;
641a8ab6541SSrinivas Kandagatla 	param_data->module_instance_id = module->instance_id;
642a8ab6541SSrinivas Kandagatla 	param_data->error_code = 0;
643a8ab6541SSrinivas Kandagatla 	param_data->param_id = PARAM_ID_DISPLAY_PORT_INTF_CFG;
644a8ab6541SSrinivas Kandagatla 	param_data->param_size = ic_sz - APM_MODULE_PARAM_DATA_SIZE;
645a8ab6541SSrinivas Kandagatla 
646a8ab6541SSrinivas Kandagatla 	intf_cfg->cfg.channel_allocation = cfg->channel_allocation;
647a8ab6541SSrinivas Kandagatla 	intf_cfg->cfg.mst_idx = 0;
648a8ab6541SSrinivas Kandagatla 	intf_cfg->cfg.dptx_idx = cfg->dp_idx;
649a8ab6541SSrinivas Kandagatla 
650a8ab6541SSrinivas Kandagatla 	rc = q6apm_send_cmd_sync(graph->apm, pkt, 0);
651a8ab6541SSrinivas Kandagatla 
652a8ab6541SSrinivas Kandagatla 	kfree(pkt);
653a8ab6541SSrinivas Kandagatla 
654a8ab6541SSrinivas Kandagatla 	return rc;
655a8ab6541SSrinivas Kandagatla }
656a8ab6541SSrinivas Kandagatla 
65725ab80dbSSrinivas Kandagatla /* LPASS Codec DMA port Module Media Format Setup */
audioreach_codec_dma_set_media_format(struct q6apm_graph * graph,struct audioreach_module * module,struct audioreach_module_config * cfg)65825ab80dbSSrinivas Kandagatla static int audioreach_codec_dma_set_media_format(struct q6apm_graph *graph,
65925ab80dbSSrinivas Kandagatla 						 struct audioreach_module *module,
66025ab80dbSSrinivas Kandagatla 						 struct audioreach_module_config *cfg)
66125ab80dbSSrinivas Kandagatla {
66225ab80dbSSrinivas Kandagatla 	struct apm_codec_dma_module_intf_cfg *intf_cfg;
66325ab80dbSSrinivas Kandagatla 	struct apm_module_frame_size_factor_cfg *fs_cfg;
66425ab80dbSSrinivas Kandagatla 	struct apm_module_hw_ep_power_mode_cfg *pm_cfg;
66525ab80dbSSrinivas Kandagatla 	struct apm_module_param_data *param_data;
66625ab80dbSSrinivas Kandagatla 	struct apm_module_hw_ep_mf_cfg *hw_cfg;
66725ab80dbSSrinivas Kandagatla 	int ic_sz, ep_sz, fs_sz, pm_sz, dl_sz;
66825ab80dbSSrinivas Kandagatla 	int rc, payload_size;
66925ab80dbSSrinivas Kandagatla 	struct gpr_pkt *pkt;
67025ab80dbSSrinivas Kandagatla 	void *p;
67125ab80dbSSrinivas Kandagatla 
67225ab80dbSSrinivas Kandagatla 	ic_sz = APM_CDMA_INTF_CFG_PSIZE;
67325ab80dbSSrinivas Kandagatla 	ep_sz = APM_HW_EP_CFG_PSIZE;
67425ab80dbSSrinivas Kandagatla 	fs_sz = APM_FS_CFG_PSIZE;
67525ab80dbSSrinivas Kandagatla 	pm_sz = APM_HW_EP_PMODE_CFG_PSIZE;
67625ab80dbSSrinivas Kandagatla 	dl_sz = 0;
67725ab80dbSSrinivas Kandagatla 
67825ab80dbSSrinivas Kandagatla 	payload_size = ic_sz + ep_sz + fs_sz + pm_sz + dl_sz;
67925ab80dbSSrinivas Kandagatla 
68025ab80dbSSrinivas Kandagatla 	pkt = audioreach_alloc_apm_cmd_pkt(payload_size, APM_CMD_SET_CFG, 0);
68125ab80dbSSrinivas Kandagatla 	if (IS_ERR(pkt))
68225ab80dbSSrinivas Kandagatla 		return PTR_ERR(pkt);
68325ab80dbSSrinivas Kandagatla 
68425ab80dbSSrinivas Kandagatla 	p = (void *)pkt + GPR_HDR_SIZE + APM_CMD_HDR_SIZE;
68525ab80dbSSrinivas Kandagatla 
68625ab80dbSSrinivas Kandagatla 	hw_cfg = p;
68725ab80dbSSrinivas Kandagatla 	param_data = &hw_cfg->param_data;
68825ab80dbSSrinivas Kandagatla 	param_data->module_instance_id = module->instance_id;
68925ab80dbSSrinivas Kandagatla 	param_data->error_code = 0;
69025ab80dbSSrinivas Kandagatla 	param_data->param_id = PARAM_ID_HW_EP_MF_CFG;
69125ab80dbSSrinivas Kandagatla 	param_data->param_size = ep_sz - APM_MODULE_PARAM_DATA_SIZE;
69225ab80dbSSrinivas Kandagatla 
69325ab80dbSSrinivas Kandagatla 	hw_cfg->mf.sample_rate = cfg->sample_rate;
69425ab80dbSSrinivas Kandagatla 	hw_cfg->mf.bit_width = cfg->bit_width;
69525ab80dbSSrinivas Kandagatla 	hw_cfg->mf.num_channels = cfg->num_channels;
69625ab80dbSSrinivas Kandagatla 	hw_cfg->mf.data_format = module->data_format;
69725ab80dbSSrinivas Kandagatla 	p += ep_sz;
69825ab80dbSSrinivas Kandagatla 
69925ab80dbSSrinivas Kandagatla 	fs_cfg = p;
70025ab80dbSSrinivas Kandagatla 	param_data = &fs_cfg->param_data;
70125ab80dbSSrinivas Kandagatla 	param_data->module_instance_id = module->instance_id;
70225ab80dbSSrinivas Kandagatla 	param_data->error_code = 0;
70325ab80dbSSrinivas Kandagatla 	param_data->param_id = PARAM_ID_HW_EP_FRAME_SIZE_FACTOR;
70425ab80dbSSrinivas Kandagatla 	param_data->param_size = fs_sz - APM_MODULE_PARAM_DATA_SIZE;
70525ab80dbSSrinivas Kandagatla 	fs_cfg->frame_size_factor = 1;
70625ab80dbSSrinivas Kandagatla 	p += fs_sz;
70725ab80dbSSrinivas Kandagatla 
70825ab80dbSSrinivas Kandagatla 	intf_cfg = p;
70925ab80dbSSrinivas Kandagatla 	param_data = &intf_cfg->param_data;
71025ab80dbSSrinivas Kandagatla 	param_data->module_instance_id = module->instance_id;
71125ab80dbSSrinivas Kandagatla 	param_data->error_code = 0;
71225ab80dbSSrinivas Kandagatla 	param_data->param_id = PARAM_ID_CODEC_DMA_INTF_CFG;
71325ab80dbSSrinivas Kandagatla 	param_data->param_size = ic_sz - APM_MODULE_PARAM_DATA_SIZE;
71425ab80dbSSrinivas Kandagatla 
71525ab80dbSSrinivas Kandagatla 	intf_cfg->cfg.lpaif_type = module->hw_interface_type;
71625ab80dbSSrinivas Kandagatla 	intf_cfg->cfg.intf_index = module->hw_interface_idx;
71725ab80dbSSrinivas Kandagatla 	intf_cfg->cfg.active_channels_mask = (1 << cfg->num_channels) - 1;
71825ab80dbSSrinivas Kandagatla 	p += ic_sz;
71925ab80dbSSrinivas Kandagatla 
72025ab80dbSSrinivas Kandagatla 	pm_cfg = p;
72125ab80dbSSrinivas Kandagatla 	param_data = &pm_cfg->param_data;
72225ab80dbSSrinivas Kandagatla 	param_data->module_instance_id = module->instance_id;
72325ab80dbSSrinivas Kandagatla 	param_data->error_code = 0;
72425ab80dbSSrinivas Kandagatla 	param_data->param_id = PARAM_ID_HW_EP_POWER_MODE_CFG;
72525ab80dbSSrinivas Kandagatla 	param_data->param_size = pm_sz - APM_MODULE_PARAM_DATA_SIZE;
72625ab80dbSSrinivas Kandagatla 	pm_cfg->power_mode.power_mode = 0;
72725ab80dbSSrinivas Kandagatla 
72825ab80dbSSrinivas Kandagatla 	rc = q6apm_send_cmd_sync(graph->apm, pkt, 0);
72925ab80dbSSrinivas Kandagatla 
73025ab80dbSSrinivas Kandagatla 	kfree(pkt);
73125ab80dbSSrinivas Kandagatla 
73225ab80dbSSrinivas Kandagatla 	return rc;
73325ab80dbSSrinivas Kandagatla }
73425ab80dbSSrinivas Kandagatla 
audioreach_send_u32_param(struct q6apm_graph * graph,struct audioreach_module * module,uint32_t param_id,uint32_t param_val)73569bff594SSrinivas Kandagatla int audioreach_send_u32_param(struct q6apm_graph *graph, struct audioreach_module *module,
73669bff594SSrinivas Kandagatla 			      uint32_t param_id, uint32_t param_val)
737a934afdbSSrinivas Kandagatla {
738a934afdbSSrinivas Kandagatla 	struct apm_module_param_data *param_data;
739a934afdbSSrinivas Kandagatla 	struct gpr_pkt *pkt;
74069bff594SSrinivas Kandagatla 	uint32_t *param;
74169bff594SSrinivas Kandagatla 	int rc, payload_size;
742a934afdbSSrinivas Kandagatla 	void *p;
743a934afdbSSrinivas Kandagatla 
74469bff594SSrinivas Kandagatla 	payload_size = sizeof(uint32_t) + APM_MODULE_PARAM_DATA_SIZE;
74569bff594SSrinivas Kandagatla 	p = audioreach_alloc_apm_cmd_pkt(payload_size, APM_CMD_SET_CFG, 0);
74669bff594SSrinivas Kandagatla 	if (IS_ERR(p))
74769bff594SSrinivas Kandagatla 		return -ENOMEM;
748a934afdbSSrinivas Kandagatla 
74969bff594SSrinivas Kandagatla 	pkt = p;
75069bff594SSrinivas Kandagatla 	p = p + GPR_HDR_SIZE + APM_CMD_HDR_SIZE;
751a934afdbSSrinivas Kandagatla 
752a934afdbSSrinivas Kandagatla 	param_data = p;
753a934afdbSSrinivas Kandagatla 	param_data->module_instance_id = module->instance_id;
754a934afdbSSrinivas Kandagatla 	param_data->error_code = 0;
75569bff594SSrinivas Kandagatla 	param_data->param_id = param_id;
75669bff594SSrinivas Kandagatla 	param_data->param_size = sizeof(uint32_t);
757a934afdbSSrinivas Kandagatla 
75869bff594SSrinivas Kandagatla 	p = p + APM_MODULE_PARAM_DATA_SIZE;
75969bff594SSrinivas Kandagatla 	param = p;
76069bff594SSrinivas Kandagatla 	*param = param_val;
761a934afdbSSrinivas Kandagatla 
762a934afdbSSrinivas Kandagatla 	rc = q6apm_send_cmd_sync(graph->apm, pkt, 0);
763a934afdbSSrinivas Kandagatla 
764a934afdbSSrinivas Kandagatla 	kfree(pkt);
765a934afdbSSrinivas Kandagatla 
766a934afdbSSrinivas Kandagatla 	return rc;
767a934afdbSSrinivas Kandagatla }
76869bff594SSrinivas Kandagatla EXPORT_SYMBOL_GPL(audioreach_send_u32_param);
76969bff594SSrinivas Kandagatla 
audioreach_sal_limiter_enable(struct q6apm_graph * graph,struct audioreach_module * module,bool enable)77069bff594SSrinivas Kandagatla static int audioreach_sal_limiter_enable(struct q6apm_graph *graph,
77169bff594SSrinivas Kandagatla 					 struct audioreach_module *module, bool enable)
77269bff594SSrinivas Kandagatla {
77369bff594SSrinivas Kandagatla 	return audioreach_send_u32_param(graph, module, PARAM_ID_SAL_LIMITER_ENABLE, enable);
77469bff594SSrinivas Kandagatla }
775a934afdbSSrinivas Kandagatla 
audioreach_sal_set_media_format(struct q6apm_graph * graph,struct audioreach_module * module,struct audioreach_module_config * cfg)776a934afdbSSrinivas Kandagatla static int audioreach_sal_set_media_format(struct q6apm_graph *graph,
777a934afdbSSrinivas Kandagatla 					   struct audioreach_module *module,
778a934afdbSSrinivas Kandagatla 					   struct audioreach_module_config *cfg)
779a934afdbSSrinivas Kandagatla {
78069bff594SSrinivas Kandagatla 	return audioreach_send_u32_param(graph, module, PARAM_ID_SAL_OUTPUT_CFG,  cfg->bit_width);
781a934afdbSSrinivas Kandagatla }
782a934afdbSSrinivas Kandagatla 
audioreach_module_enable(struct q6apm_graph * graph,struct audioreach_module * module,bool enable)7836648a6dcSSrinivas Kandagatla static int audioreach_module_enable(struct q6apm_graph *graph,
7846648a6dcSSrinivas Kandagatla 				    struct audioreach_module *module,
7856648a6dcSSrinivas Kandagatla 				    bool enable)
7866648a6dcSSrinivas Kandagatla {
78769bff594SSrinivas Kandagatla 	return audioreach_send_u32_param(graph, module, PARAM_ID_MODULE_ENABLE, enable);
7886648a6dcSSrinivas Kandagatla }
7896648a6dcSSrinivas Kandagatla 
audioreach_gapless_set_media_format(struct q6apm_graph * graph,struct audioreach_module * module,struct audioreach_module_config * cfg)790*2c954a37SMohammad Rafi Shaik static int audioreach_gapless_set_media_format(struct q6apm_graph *graph,
791*2c954a37SMohammad Rafi Shaik 					       struct audioreach_module *module,
792*2c954a37SMohammad Rafi Shaik 					       struct audioreach_module_config *cfg)
793*2c954a37SMohammad Rafi Shaik {
794*2c954a37SMohammad Rafi Shaik 	return audioreach_send_u32_param(graph, module, PARAM_ID_EARLY_EOS_DELAY,
795*2c954a37SMohammad Rafi Shaik 					 EARLY_EOS_DELAY_MS);
796*2c954a37SMohammad Rafi Shaik }
797*2c954a37SMohammad Rafi Shaik 
audioreach_mfc_set_media_format(struct q6apm_graph * graph,struct audioreach_module * module,struct audioreach_module_config * cfg)798cf0de67dSSrinivas Kandagatla static int audioreach_mfc_set_media_format(struct q6apm_graph *graph,
799cf0de67dSSrinivas Kandagatla 					   struct audioreach_module *module,
800cf0de67dSSrinivas Kandagatla 					   struct audioreach_module_config *cfg)
801cf0de67dSSrinivas Kandagatla {
802cf0de67dSSrinivas Kandagatla 	struct apm_module_param_data *param_data;
803cf0de67dSSrinivas Kandagatla 	struct param_id_mfc_media_format *media_format;
804cf0de67dSSrinivas Kandagatla 	uint32_t num_channels = cfg->num_channels;
805cf0de67dSSrinivas Kandagatla 	int payload_size;
806cf0de67dSSrinivas Kandagatla 	struct gpr_pkt *pkt;
807cf0de67dSSrinivas Kandagatla 	int rc;
808cf0de67dSSrinivas Kandagatla 	void *p;
809cf0de67dSSrinivas Kandagatla 
810cf0de67dSSrinivas Kandagatla 	payload_size = APM_MFC_CFG_PSIZE(media_format, num_channels) +
811cf0de67dSSrinivas Kandagatla 		APM_MODULE_PARAM_DATA_SIZE;
812cf0de67dSSrinivas Kandagatla 
813cf0de67dSSrinivas Kandagatla 	pkt = audioreach_alloc_apm_cmd_pkt(payload_size, APM_CMD_SET_CFG, 0);
814cf0de67dSSrinivas Kandagatla 	if (IS_ERR(pkt))
815cf0de67dSSrinivas Kandagatla 		return PTR_ERR(pkt);
816cf0de67dSSrinivas Kandagatla 
817cf0de67dSSrinivas Kandagatla 	p = (void *)pkt + GPR_HDR_SIZE + APM_CMD_HDR_SIZE;
818cf0de67dSSrinivas Kandagatla 
819cf0de67dSSrinivas Kandagatla 	param_data = p;
820cf0de67dSSrinivas Kandagatla 	param_data->module_instance_id = module->instance_id;
821cf0de67dSSrinivas Kandagatla 	param_data->error_code = 0;
822cf0de67dSSrinivas Kandagatla 	param_data->param_id = PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT;
823cf0de67dSSrinivas Kandagatla 	param_data->param_size = APM_MFC_CFG_PSIZE(media_format, num_channels);
824cf0de67dSSrinivas Kandagatla 	p = p + APM_MODULE_PARAM_DATA_SIZE;
825cf0de67dSSrinivas Kandagatla 	media_format = p;
826cf0de67dSSrinivas Kandagatla 
827cf0de67dSSrinivas Kandagatla 	media_format->sample_rate = cfg->sample_rate;
828cf0de67dSSrinivas Kandagatla 	media_format->bit_width = cfg->bit_width;
829cf0de67dSSrinivas Kandagatla 	media_format->num_channels = cfg->num_channels;
830cf0de67dSSrinivas Kandagatla 
831cf0de67dSSrinivas Kandagatla 	if (num_channels == 1) {
832cf0de67dSSrinivas Kandagatla 		media_format->channel_mapping[0] = PCM_CHANNEL_L;
833cf0de67dSSrinivas Kandagatla 	} else if (num_channels == 2) {
834cf0de67dSSrinivas Kandagatla 		media_format->channel_mapping[0] = PCM_CHANNEL_L;
835cf0de67dSSrinivas Kandagatla 		media_format->channel_mapping[1] = PCM_CHANNEL_R;
836cf0de67dSSrinivas Kandagatla 	}
837cf0de67dSSrinivas Kandagatla 
838cf0de67dSSrinivas Kandagatla 	rc = q6apm_send_cmd_sync(graph->apm, pkt, 0);
839cf0de67dSSrinivas Kandagatla 
840cf0de67dSSrinivas Kandagatla 	kfree(pkt);
841cf0de67dSSrinivas Kandagatla 
842cf0de67dSSrinivas Kandagatla 	return rc;
843cf0de67dSSrinivas Kandagatla }
844cf0de67dSSrinivas Kandagatla 
audioreach_set_compr_media_format(struct media_format * media_fmt_hdr,void * p,struct audioreach_module_config * mcfg)845e41521b6SMohammad Rafi Shaik static int audioreach_set_compr_media_format(struct media_format *media_fmt_hdr,
846e41521b6SMohammad Rafi Shaik 					     void *p, struct audioreach_module_config *mcfg)
847e41521b6SMohammad Rafi Shaik {
848e41521b6SMohammad Rafi Shaik 	struct payload_media_fmt_aac_t *aac_cfg;
849e41521b6SMohammad Rafi Shaik 	struct payload_media_fmt_pcm *mp3_cfg;
850e41521b6SMohammad Rafi Shaik 	struct payload_media_fmt_flac_t *flac_cfg;
851e41521b6SMohammad Rafi Shaik 
852e41521b6SMohammad Rafi Shaik 	switch (mcfg->fmt) {
853e41521b6SMohammad Rafi Shaik 	case SND_AUDIOCODEC_MP3:
854e41521b6SMohammad Rafi Shaik 		media_fmt_hdr->data_format = DATA_FORMAT_RAW_COMPRESSED;
855e41521b6SMohammad Rafi Shaik 		media_fmt_hdr->fmt_id = MEDIA_FMT_ID_MP3;
856e41521b6SMohammad Rafi Shaik 		media_fmt_hdr->payload_size = 0;
857e41521b6SMohammad Rafi Shaik 		p = p + sizeof(*media_fmt_hdr);
858e41521b6SMohammad Rafi Shaik 		mp3_cfg = p;
859e41521b6SMohammad Rafi Shaik 		mp3_cfg->sample_rate = mcfg->sample_rate;
860e41521b6SMohammad Rafi Shaik 		mp3_cfg->bit_width = mcfg->bit_width;
861e41521b6SMohammad Rafi Shaik 		mp3_cfg->alignment = PCM_LSB_ALIGNED;
862e41521b6SMohammad Rafi Shaik 		mp3_cfg->bits_per_sample = mcfg->bit_width;
863e41521b6SMohammad Rafi Shaik 		mp3_cfg->q_factor = mcfg->bit_width - 1;
864e41521b6SMohammad Rafi Shaik 		mp3_cfg->endianness = PCM_LITTLE_ENDIAN;
865e41521b6SMohammad Rafi Shaik 		mp3_cfg->num_channels = mcfg->num_channels;
866e41521b6SMohammad Rafi Shaik 
867e41521b6SMohammad Rafi Shaik 		if (mcfg->num_channels == 1) {
868e41521b6SMohammad Rafi Shaik 			mp3_cfg->channel_mapping[0] =  PCM_CHANNEL_L;
869e41521b6SMohammad Rafi Shaik 		} else if (mcfg->num_channels == 2) {
870e41521b6SMohammad Rafi Shaik 			mp3_cfg->channel_mapping[0] =  PCM_CHANNEL_L;
871e41521b6SMohammad Rafi Shaik 			mp3_cfg->channel_mapping[1] =  PCM_CHANNEL_R;
872e41521b6SMohammad Rafi Shaik 		}
873e41521b6SMohammad Rafi Shaik 		break;
874e41521b6SMohammad Rafi Shaik 	case SND_AUDIOCODEC_AAC:
875e41521b6SMohammad Rafi Shaik 		media_fmt_hdr->data_format = DATA_FORMAT_RAW_COMPRESSED;
876e41521b6SMohammad Rafi Shaik 		media_fmt_hdr->fmt_id = MEDIA_FMT_ID_AAC;
877e41521b6SMohammad Rafi Shaik 		media_fmt_hdr->payload_size = sizeof(struct payload_media_fmt_aac_t);
878e41521b6SMohammad Rafi Shaik 		p = p + sizeof(*media_fmt_hdr);
879e41521b6SMohammad Rafi Shaik 		aac_cfg = p;
880e41521b6SMohammad Rafi Shaik 		aac_cfg->aac_fmt_flag = 0;
881e41521b6SMohammad Rafi Shaik 		aac_cfg->audio_obj_type = 5;
882e41521b6SMohammad Rafi Shaik 		aac_cfg->num_channels = mcfg->num_channels;
883e41521b6SMohammad Rafi Shaik 		aac_cfg->total_size_of_PCE_bits = 0;
884e41521b6SMohammad Rafi Shaik 		aac_cfg->sample_rate = mcfg->sample_rate;
885e41521b6SMohammad Rafi Shaik 		break;
886e41521b6SMohammad Rafi Shaik 	case SND_AUDIOCODEC_FLAC:
887e41521b6SMohammad Rafi Shaik 		media_fmt_hdr->data_format = DATA_FORMAT_RAW_COMPRESSED;
888e41521b6SMohammad Rafi Shaik 		media_fmt_hdr->fmt_id = MEDIA_FMT_ID_FLAC;
889e41521b6SMohammad Rafi Shaik 		media_fmt_hdr->payload_size = sizeof(struct payload_media_fmt_flac_t);
890e41521b6SMohammad Rafi Shaik 		p = p + sizeof(*media_fmt_hdr);
891e41521b6SMohammad Rafi Shaik 		flac_cfg = p;
892e41521b6SMohammad Rafi Shaik 		flac_cfg->sample_size = mcfg->codec.options.flac_d.sample_size;
893e41521b6SMohammad Rafi Shaik 		flac_cfg->num_channels = mcfg->num_channels;
894e41521b6SMohammad Rafi Shaik 		flac_cfg->min_blk_size = mcfg->codec.options.flac_d.min_blk_size;
895e41521b6SMohammad Rafi Shaik 		flac_cfg->max_blk_size = mcfg->codec.options.flac_d.max_blk_size;
896e41521b6SMohammad Rafi Shaik 		flac_cfg->sample_rate = mcfg->sample_rate;
897e41521b6SMohammad Rafi Shaik 		flac_cfg->min_frame_size = mcfg->codec.options.flac_d.min_frame_size;
898e41521b6SMohammad Rafi Shaik 		flac_cfg->max_frame_size = mcfg->codec.options.flac_d.max_frame_size;
899e41521b6SMohammad Rafi Shaik 		break;
900e41521b6SMohammad Rafi Shaik 	default:
901e41521b6SMohammad Rafi Shaik 		return -EINVAL;
902e41521b6SMohammad Rafi Shaik 	}
903e41521b6SMohammad Rafi Shaik 
904e41521b6SMohammad Rafi Shaik 	return 0;
905e41521b6SMohammad Rafi Shaik }
906e41521b6SMohammad Rafi Shaik 
audioreach_compr_set_param(struct q6apm_graph * graph,struct audioreach_module_config * mcfg)907e41521b6SMohammad Rafi Shaik int audioreach_compr_set_param(struct q6apm_graph *graph, struct audioreach_module_config *mcfg)
908e41521b6SMohammad Rafi Shaik {
909e41521b6SMohammad Rafi Shaik 	struct media_format *header;
910e41521b6SMohammad Rafi Shaik 	struct gpr_pkt *pkt;
911e41521b6SMohammad Rafi Shaik 	int iid, payload_size, rc;
912e41521b6SMohammad Rafi Shaik 	void *p;
913e41521b6SMohammad Rafi Shaik 
914e41521b6SMohammad Rafi Shaik 	payload_size = sizeof(struct apm_sh_module_media_fmt_cmd);
915e41521b6SMohammad Rafi Shaik 
916e41521b6SMohammad Rafi Shaik 	iid = q6apm_graph_get_rx_shmem_module_iid(graph);
917e41521b6SMohammad Rafi Shaik 	pkt = audioreach_alloc_cmd_pkt(payload_size, DATA_CMD_WR_SH_MEM_EP_MEDIA_FORMAT,
918e41521b6SMohammad Rafi Shaik 			0, graph->port->id, iid);
919e41521b6SMohammad Rafi Shaik 
920e41521b6SMohammad Rafi Shaik 	if (IS_ERR(pkt))
921e41521b6SMohammad Rafi Shaik 		return -ENOMEM;
922e41521b6SMohammad Rafi Shaik 
923e41521b6SMohammad Rafi Shaik 	p = (void *)pkt + GPR_HDR_SIZE;
924e41521b6SMohammad Rafi Shaik 	header = p;
925e41521b6SMohammad Rafi Shaik 	rc = audioreach_set_compr_media_format(header, p, mcfg);
926e41521b6SMohammad Rafi Shaik 	if (rc) {
927e41521b6SMohammad Rafi Shaik 		kfree(pkt);
928e41521b6SMohammad Rafi Shaik 		return rc;
929e41521b6SMohammad Rafi Shaik 	}
930e41521b6SMohammad Rafi Shaik 
931e41521b6SMohammad Rafi Shaik 	rc = gpr_send_port_pkt(graph->port, pkt);
932e41521b6SMohammad Rafi Shaik 	kfree(pkt);
933e41521b6SMohammad Rafi Shaik 
934e41521b6SMohammad Rafi Shaik 	return rc;
935e41521b6SMohammad Rafi Shaik }
936e41521b6SMohammad Rafi Shaik EXPORT_SYMBOL_GPL(audioreach_compr_set_param);
937e41521b6SMohammad Rafi Shaik 
audioreach_i2s_set_media_format(struct q6apm_graph * graph,struct audioreach_module * module,struct audioreach_module_config * cfg)93825ab80dbSSrinivas Kandagatla static int audioreach_i2s_set_media_format(struct q6apm_graph *graph,
93925ab80dbSSrinivas Kandagatla 					   struct audioreach_module *module,
94025ab80dbSSrinivas Kandagatla 					   struct audioreach_module_config *cfg)
94125ab80dbSSrinivas Kandagatla {
94225ab80dbSSrinivas Kandagatla 	struct apm_module_frame_size_factor_cfg *fs_cfg;
94325ab80dbSSrinivas Kandagatla 	struct apm_module_param_data *param_data;
94425ab80dbSSrinivas Kandagatla 	struct apm_i2s_module_intf_cfg *intf_cfg;
94525ab80dbSSrinivas Kandagatla 	struct apm_module_hw_ep_mf_cfg *hw_cfg;
94625ab80dbSSrinivas Kandagatla 	int ic_sz, ep_sz, fs_sz;
94725ab80dbSSrinivas Kandagatla 	int rc, payload_size;
94825ab80dbSSrinivas Kandagatla 	struct gpr_pkt *pkt;
94925ab80dbSSrinivas Kandagatla 	void *p;
95025ab80dbSSrinivas Kandagatla 
95125ab80dbSSrinivas Kandagatla 	ic_sz = APM_I2S_INTF_CFG_PSIZE;
95225ab80dbSSrinivas Kandagatla 	ep_sz = APM_HW_EP_CFG_PSIZE;
95325ab80dbSSrinivas Kandagatla 	fs_sz = APM_FS_CFG_PSIZE;
95425ab80dbSSrinivas Kandagatla 
95525ab80dbSSrinivas Kandagatla 	payload_size = ic_sz + ep_sz + fs_sz;
95625ab80dbSSrinivas Kandagatla 
95725ab80dbSSrinivas Kandagatla 	pkt = audioreach_alloc_apm_cmd_pkt(payload_size, APM_CMD_SET_CFG, 0);
95825ab80dbSSrinivas Kandagatla 	if (IS_ERR(pkt))
95925ab80dbSSrinivas Kandagatla 		return PTR_ERR(pkt);
96025ab80dbSSrinivas Kandagatla 
96125ab80dbSSrinivas Kandagatla 	p = (void *)pkt + GPR_HDR_SIZE + APM_CMD_HDR_SIZE;
96225ab80dbSSrinivas Kandagatla 	intf_cfg = p;
96325ab80dbSSrinivas Kandagatla 
96425ab80dbSSrinivas Kandagatla 	param_data = &intf_cfg->param_data;
96525ab80dbSSrinivas Kandagatla 	param_data->module_instance_id = module->instance_id;
96625ab80dbSSrinivas Kandagatla 	param_data->error_code = 0;
96725ab80dbSSrinivas Kandagatla 	param_data->param_id = PARAM_ID_I2S_INTF_CFG;
96825ab80dbSSrinivas Kandagatla 	param_data->param_size = ic_sz - APM_MODULE_PARAM_DATA_SIZE;
96925ab80dbSSrinivas Kandagatla 
97025ab80dbSSrinivas Kandagatla 	intf_cfg->cfg.intf_idx = module->hw_interface_idx;
97125ab80dbSSrinivas Kandagatla 	intf_cfg->cfg.sd_line_idx = module->sd_line_idx;
97225ab80dbSSrinivas Kandagatla 
97325ab80dbSSrinivas Kandagatla 	switch (cfg->fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
9741148e16bSCharles Keepax 	case SND_SOC_DAIFMT_BP_FP:
97525ab80dbSSrinivas Kandagatla 		intf_cfg->cfg.ws_src = CONFIG_I2S_WS_SRC_INTERNAL;
97625ab80dbSSrinivas Kandagatla 		break;
9771148e16bSCharles Keepax 	case SND_SOC_DAIFMT_BC_FC:
97825ab80dbSSrinivas Kandagatla 		/* CPU is slave */
97925ab80dbSSrinivas Kandagatla 		intf_cfg->cfg.ws_src = CONFIG_I2S_WS_SRC_EXTERNAL;
98025ab80dbSSrinivas Kandagatla 		break;
98125ab80dbSSrinivas Kandagatla 	default:
98225ab80dbSSrinivas Kandagatla 		break;
98325ab80dbSSrinivas Kandagatla 	}
98425ab80dbSSrinivas Kandagatla 
98525ab80dbSSrinivas Kandagatla 	p += ic_sz;
98625ab80dbSSrinivas Kandagatla 	hw_cfg = p;
98725ab80dbSSrinivas Kandagatla 	param_data = &hw_cfg->param_data;
98825ab80dbSSrinivas Kandagatla 	param_data->module_instance_id = module->instance_id;
98925ab80dbSSrinivas Kandagatla 	param_data->error_code = 0;
99025ab80dbSSrinivas Kandagatla 	param_data->param_id = PARAM_ID_HW_EP_MF_CFG;
99125ab80dbSSrinivas Kandagatla 	param_data->param_size = ep_sz - APM_MODULE_PARAM_DATA_SIZE;
99225ab80dbSSrinivas Kandagatla 
99325ab80dbSSrinivas Kandagatla 	hw_cfg->mf.sample_rate = cfg->sample_rate;
99425ab80dbSSrinivas Kandagatla 	hw_cfg->mf.bit_width = cfg->bit_width;
99525ab80dbSSrinivas Kandagatla 	hw_cfg->mf.num_channels = cfg->num_channels;
99625ab80dbSSrinivas Kandagatla 	hw_cfg->mf.data_format = module->data_format;
99725ab80dbSSrinivas Kandagatla 
99825ab80dbSSrinivas Kandagatla 	p += ep_sz;
99925ab80dbSSrinivas Kandagatla 	fs_cfg = p;
100025ab80dbSSrinivas Kandagatla 	param_data = &fs_cfg->param_data;
100125ab80dbSSrinivas Kandagatla 	param_data->module_instance_id = module->instance_id;
100225ab80dbSSrinivas Kandagatla 	param_data->error_code = 0;
100325ab80dbSSrinivas Kandagatla 	param_data->param_id = PARAM_ID_HW_EP_FRAME_SIZE_FACTOR;
100425ab80dbSSrinivas Kandagatla 	param_data->param_size = fs_sz - APM_MODULE_PARAM_DATA_SIZE;
100525ab80dbSSrinivas Kandagatla 	fs_cfg->frame_size_factor = 1;
100625ab80dbSSrinivas Kandagatla 
100725ab80dbSSrinivas Kandagatla 	rc = q6apm_send_cmd_sync(graph->apm, pkt, 0);
100825ab80dbSSrinivas Kandagatla 
100925ab80dbSSrinivas Kandagatla 	kfree(pkt);
101025ab80dbSSrinivas Kandagatla 
101125ab80dbSSrinivas Kandagatla 	return rc;
101225ab80dbSSrinivas Kandagatla }
101325ab80dbSSrinivas Kandagatla 
audioreach_logging_set_media_format(struct q6apm_graph * graph,struct audioreach_module * module)101425ab80dbSSrinivas Kandagatla static int audioreach_logging_set_media_format(struct q6apm_graph *graph,
101525ab80dbSSrinivas Kandagatla 					       struct audioreach_module *module)
101625ab80dbSSrinivas Kandagatla {
101725ab80dbSSrinivas Kandagatla 	struct apm_module_param_data *param_data;
101825ab80dbSSrinivas Kandagatla 	struct data_logging_config *cfg;
101925ab80dbSSrinivas Kandagatla 	int rc, payload_size;
102025ab80dbSSrinivas Kandagatla 	struct gpr_pkt *pkt;
102125ab80dbSSrinivas Kandagatla 	void *p;
102225ab80dbSSrinivas Kandagatla 
102325ab80dbSSrinivas Kandagatla 	payload_size = sizeof(*cfg) + APM_MODULE_PARAM_DATA_SIZE;
102425ab80dbSSrinivas Kandagatla 	pkt = audioreach_alloc_apm_cmd_pkt(payload_size, APM_CMD_SET_CFG, 0);
102525ab80dbSSrinivas Kandagatla 	if (IS_ERR(pkt))
102625ab80dbSSrinivas Kandagatla 		return PTR_ERR(pkt);
102725ab80dbSSrinivas Kandagatla 
102825ab80dbSSrinivas Kandagatla 	p = (void *)pkt + GPR_HDR_SIZE + APM_CMD_HDR_SIZE;
102925ab80dbSSrinivas Kandagatla 
103025ab80dbSSrinivas Kandagatla 	param_data = p;
103125ab80dbSSrinivas Kandagatla 	param_data->module_instance_id = module->instance_id;
103225ab80dbSSrinivas Kandagatla 	param_data->error_code = 0;
103325ab80dbSSrinivas Kandagatla 	param_data->param_id = PARAM_ID_DATA_LOGGING_CONFIG;
103425ab80dbSSrinivas Kandagatla 	param_data->param_size = payload_size - APM_MODULE_PARAM_DATA_SIZE;
103525ab80dbSSrinivas Kandagatla 
103625ab80dbSSrinivas Kandagatla 	p = p + APM_MODULE_PARAM_DATA_SIZE;
103725ab80dbSSrinivas Kandagatla 	cfg = p;
103825ab80dbSSrinivas Kandagatla 	cfg->log_code = module->log_code;
103925ab80dbSSrinivas Kandagatla 	cfg->log_tap_point_id = module->log_tap_point_id;
104025ab80dbSSrinivas Kandagatla 	cfg->mode = module->log_mode;
104125ab80dbSSrinivas Kandagatla 
104225ab80dbSSrinivas Kandagatla 	rc = q6apm_send_cmd_sync(graph->apm, pkt, 0);
104325ab80dbSSrinivas Kandagatla 
104425ab80dbSSrinivas Kandagatla 	kfree(pkt);
104525ab80dbSSrinivas Kandagatla 
104625ab80dbSSrinivas Kandagatla 	return rc;
104725ab80dbSSrinivas Kandagatla }
104825ab80dbSSrinivas Kandagatla 
audioreach_pcm_set_media_format(struct q6apm_graph * graph,struct audioreach_module * module,struct audioreach_module_config * mcfg)104925ab80dbSSrinivas Kandagatla static int audioreach_pcm_set_media_format(struct q6apm_graph *graph,
105025ab80dbSSrinivas Kandagatla 					   struct audioreach_module *module,
105125ab80dbSSrinivas Kandagatla 					   struct audioreach_module_config *mcfg)
105225ab80dbSSrinivas Kandagatla {
105325ab80dbSSrinivas Kandagatla 	struct payload_pcm_output_format_cfg *media_cfg;
105425ab80dbSSrinivas Kandagatla 	uint32_t num_channels = mcfg->num_channels;
105525ab80dbSSrinivas Kandagatla 	struct apm_pcm_module_media_fmt_cmd *cfg;
105625ab80dbSSrinivas Kandagatla 	struct apm_module_param_data *param_data;
105725ab80dbSSrinivas Kandagatla 	int rc, payload_size;
105825ab80dbSSrinivas Kandagatla 	struct gpr_pkt *pkt;
105925ab80dbSSrinivas Kandagatla 
106025ab80dbSSrinivas Kandagatla 	if (num_channels > 2) {
106125ab80dbSSrinivas Kandagatla 		dev_err(graph->dev, "Error: Invalid channels (%d)!\n", num_channels);
106225ab80dbSSrinivas Kandagatla 		return -EINVAL;
106325ab80dbSSrinivas Kandagatla 	}
106425ab80dbSSrinivas Kandagatla 
106525ab80dbSSrinivas Kandagatla 	payload_size = APM_PCM_MODULE_FMT_CMD_PSIZE(num_channels);
106625ab80dbSSrinivas Kandagatla 
106725ab80dbSSrinivas Kandagatla 	pkt = audioreach_alloc_apm_cmd_pkt(payload_size, APM_CMD_SET_CFG, 0);
106825ab80dbSSrinivas Kandagatla 	if (IS_ERR(pkt))
106925ab80dbSSrinivas Kandagatla 		return PTR_ERR(pkt);
107025ab80dbSSrinivas Kandagatla 
107125ab80dbSSrinivas Kandagatla 	cfg = (void *)pkt + GPR_HDR_SIZE + APM_CMD_HDR_SIZE;
107225ab80dbSSrinivas Kandagatla 
107325ab80dbSSrinivas Kandagatla 	param_data = &cfg->param_data;
107425ab80dbSSrinivas Kandagatla 	param_data->module_instance_id = module->instance_id;
107525ab80dbSSrinivas Kandagatla 	param_data->error_code = 0;
107625ab80dbSSrinivas Kandagatla 	param_data->param_id = PARAM_ID_PCM_OUTPUT_FORMAT_CFG;
107725ab80dbSSrinivas Kandagatla 	param_data->param_size = payload_size - APM_MODULE_PARAM_DATA_SIZE;
107825ab80dbSSrinivas Kandagatla 
107925ab80dbSSrinivas Kandagatla 	cfg->header.data_format = DATA_FORMAT_FIXED_POINT;
108025ab80dbSSrinivas Kandagatla 	cfg->header.fmt_id = MEDIA_FMT_ID_PCM;
108125ab80dbSSrinivas Kandagatla 	cfg->header.payload_size = APM_PCM_OUT_FMT_CFG_PSIZE(media_cfg, num_channels);
108225ab80dbSSrinivas Kandagatla 
108325ab80dbSSrinivas Kandagatla 	media_cfg = &cfg->media_cfg;
108425ab80dbSSrinivas Kandagatla 	media_cfg->alignment = PCM_LSB_ALIGNED;
108525ab80dbSSrinivas Kandagatla 	media_cfg->bit_width = mcfg->bit_width;
108625ab80dbSSrinivas Kandagatla 	media_cfg->endianness = PCM_LITTLE_ENDIAN;
108725ab80dbSSrinivas Kandagatla 	media_cfg->interleaved = module->interleave_type;
108825ab80dbSSrinivas Kandagatla 	media_cfg->num_channels = mcfg->num_channels;
108925ab80dbSSrinivas Kandagatla 	media_cfg->q_factor = mcfg->bit_width - 1;
109025ab80dbSSrinivas Kandagatla 	media_cfg->bits_per_sample = mcfg->bit_width;
109125ab80dbSSrinivas Kandagatla 
109225ab80dbSSrinivas Kandagatla 	if (num_channels == 1) {
109325ab80dbSSrinivas Kandagatla 		media_cfg->channel_mapping[0] = PCM_CHANNEL_L;
109425ab80dbSSrinivas Kandagatla 	} else if (num_channels == 2) {
109525ab80dbSSrinivas Kandagatla 		media_cfg->channel_mapping[0] = PCM_CHANNEL_L;
109625ab80dbSSrinivas Kandagatla 		media_cfg->channel_mapping[1] = PCM_CHANNEL_R;
109725ab80dbSSrinivas Kandagatla 
109825ab80dbSSrinivas Kandagatla 	}
109925ab80dbSSrinivas Kandagatla 
110025ab80dbSSrinivas Kandagatla 	rc = q6apm_send_cmd_sync(graph->apm, pkt, 0);
110125ab80dbSSrinivas Kandagatla 
110225ab80dbSSrinivas Kandagatla 	kfree(pkt);
110325ab80dbSSrinivas Kandagatla 
110425ab80dbSSrinivas Kandagatla 	return rc;
110525ab80dbSSrinivas Kandagatla }
110625ab80dbSSrinivas Kandagatla 
audioreach_shmem_set_media_format(struct q6apm_graph * graph,struct audioreach_module * module,struct audioreach_module_config * mcfg)110725ab80dbSSrinivas Kandagatla static int audioreach_shmem_set_media_format(struct q6apm_graph *graph,
110825ab80dbSSrinivas Kandagatla 					     struct audioreach_module *module,
110925ab80dbSSrinivas Kandagatla 					     struct audioreach_module_config *mcfg)
111025ab80dbSSrinivas Kandagatla {
111125ab80dbSSrinivas Kandagatla 	uint32_t num_channels = mcfg->num_channels;
111225ab80dbSSrinivas Kandagatla 	struct apm_module_param_data *param_data;
111325ab80dbSSrinivas Kandagatla 	struct payload_media_fmt_pcm *cfg;
111425ab80dbSSrinivas Kandagatla 	struct media_format *header;
111525ab80dbSSrinivas Kandagatla 	int rc, payload_size;
111625ab80dbSSrinivas Kandagatla 	struct gpr_pkt *pkt;
111725ab80dbSSrinivas Kandagatla 	void *p;
111825ab80dbSSrinivas Kandagatla 
111925ab80dbSSrinivas Kandagatla 	if (num_channels > 2) {
112025ab80dbSSrinivas Kandagatla 		dev_err(graph->dev, "Error: Invalid channels (%d)!\n", num_channels);
112125ab80dbSSrinivas Kandagatla 		return -EINVAL;
112225ab80dbSSrinivas Kandagatla 	}
112325ab80dbSSrinivas Kandagatla 
112425ab80dbSSrinivas Kandagatla 	payload_size = APM_SHMEM_FMT_CFG_PSIZE(num_channels) + APM_MODULE_PARAM_DATA_SIZE;
112525ab80dbSSrinivas Kandagatla 
112625ab80dbSSrinivas Kandagatla 	pkt = audioreach_alloc_cmd_pkt(payload_size, APM_CMD_SET_CFG, 0,
112725ab80dbSSrinivas Kandagatla 				     graph->port->id, module->instance_id);
112825ab80dbSSrinivas Kandagatla 	if (IS_ERR(pkt))
112925ab80dbSSrinivas Kandagatla 		return PTR_ERR(pkt);
113025ab80dbSSrinivas Kandagatla 
113125ab80dbSSrinivas Kandagatla 	p = (void *)pkt + GPR_HDR_SIZE + APM_CMD_HDR_SIZE;
113225ab80dbSSrinivas Kandagatla 
113325ab80dbSSrinivas Kandagatla 	param_data = p;
113425ab80dbSSrinivas Kandagatla 	param_data->module_instance_id = module->instance_id;
113525ab80dbSSrinivas Kandagatla 	param_data->error_code = 0;
113625ab80dbSSrinivas Kandagatla 	param_data->param_id = PARAM_ID_MEDIA_FORMAT;
113725ab80dbSSrinivas Kandagatla 	param_data->param_size = payload_size - APM_MODULE_PARAM_DATA_SIZE;
113825ab80dbSSrinivas Kandagatla 	p = p + APM_MODULE_PARAM_DATA_SIZE;
113925ab80dbSSrinivas Kandagatla 
114025ab80dbSSrinivas Kandagatla 	header = p;
1141e41521b6SMohammad Rafi Shaik 	if (mcfg->fmt == SND_AUDIOCODEC_PCM) {
114225ab80dbSSrinivas Kandagatla 		header->data_format = DATA_FORMAT_FIXED_POINT;
114325ab80dbSSrinivas Kandagatla 		header->fmt_id =  MEDIA_FMT_ID_PCM;
114425ab80dbSSrinivas Kandagatla 		header->payload_size = payload_size - sizeof(*header);
114525ab80dbSSrinivas Kandagatla 
114625ab80dbSSrinivas Kandagatla 		p = p + sizeof(*header);
114725ab80dbSSrinivas Kandagatla 		cfg = p;
114825ab80dbSSrinivas Kandagatla 		cfg->sample_rate = mcfg->sample_rate;
114925ab80dbSSrinivas Kandagatla 		cfg->bit_width = mcfg->bit_width;
115025ab80dbSSrinivas Kandagatla 		cfg->alignment = PCM_LSB_ALIGNED;
115125ab80dbSSrinivas Kandagatla 		cfg->bits_per_sample = mcfg->bit_width;
115225ab80dbSSrinivas Kandagatla 		cfg->q_factor = mcfg->bit_width - 1;
115325ab80dbSSrinivas Kandagatla 		cfg->endianness = PCM_LITTLE_ENDIAN;
115425ab80dbSSrinivas Kandagatla 		cfg->num_channels = mcfg->num_channels;
115525ab80dbSSrinivas Kandagatla 
1156e41521b6SMohammad Rafi Shaik 		if (mcfg->num_channels == 1)
115725ab80dbSSrinivas Kandagatla 			cfg->channel_mapping[0] =  PCM_CHANNEL_L;
1158e41521b6SMohammad Rafi Shaik 		else if (num_channels == 2) {
115925ab80dbSSrinivas Kandagatla 			cfg->channel_mapping[0] =  PCM_CHANNEL_L;
116025ab80dbSSrinivas Kandagatla 			cfg->channel_mapping[1] =  PCM_CHANNEL_R;
116125ab80dbSSrinivas Kandagatla 		}
1162e41521b6SMohammad Rafi Shaik 	} else {
1163e41521b6SMohammad Rafi Shaik 		rc = audioreach_set_compr_media_format(header, p, mcfg);
1164e41521b6SMohammad Rafi Shaik 		if (rc) {
1165e41521b6SMohammad Rafi Shaik 			kfree(pkt);
1166e41521b6SMohammad Rafi Shaik 			return rc;
1167e41521b6SMohammad Rafi Shaik 		}
1168e41521b6SMohammad Rafi Shaik 	}
116925ab80dbSSrinivas Kandagatla 
117025ab80dbSSrinivas Kandagatla 	rc = audioreach_graph_send_cmd_sync(graph, pkt, 0);
117125ab80dbSSrinivas Kandagatla 
117225ab80dbSSrinivas Kandagatla 	kfree(pkt);
117325ab80dbSSrinivas Kandagatla 
117425ab80dbSSrinivas Kandagatla 	return rc;
117525ab80dbSSrinivas Kandagatla }
117625ab80dbSSrinivas Kandagatla 
audioreach_gain_set_vol_ctrl(struct q6apm * apm,struct audioreach_module * module,int vol)117725ab80dbSSrinivas Kandagatla int audioreach_gain_set_vol_ctrl(struct q6apm *apm, struct audioreach_module *module, int vol)
117825ab80dbSSrinivas Kandagatla {
117925ab80dbSSrinivas Kandagatla 	struct param_id_vol_ctrl_master_gain *cfg;
118025ab80dbSSrinivas Kandagatla 	struct apm_module_param_data *param_data;
118125ab80dbSSrinivas Kandagatla 	int rc, payload_size;
118225ab80dbSSrinivas Kandagatla 	struct gpr_pkt *pkt;
118325ab80dbSSrinivas Kandagatla 	void *p;
118425ab80dbSSrinivas Kandagatla 
118525ab80dbSSrinivas Kandagatla 	payload_size = sizeof(*cfg) + APM_MODULE_PARAM_DATA_SIZE;
118625ab80dbSSrinivas Kandagatla 	pkt = audioreach_alloc_apm_cmd_pkt(payload_size, APM_CMD_SET_CFG, 0);
118725ab80dbSSrinivas Kandagatla 	if (IS_ERR(pkt))
118825ab80dbSSrinivas Kandagatla 		return PTR_ERR(pkt);
118925ab80dbSSrinivas Kandagatla 
119025ab80dbSSrinivas Kandagatla 	p = (void *)pkt + GPR_HDR_SIZE + APM_CMD_HDR_SIZE;
119125ab80dbSSrinivas Kandagatla 
119225ab80dbSSrinivas Kandagatla 	param_data = p;
119325ab80dbSSrinivas Kandagatla 	param_data->module_instance_id = module->instance_id;
119425ab80dbSSrinivas Kandagatla 	param_data->error_code = 0;
119525ab80dbSSrinivas Kandagatla 	param_data->param_id = PARAM_ID_VOL_CTRL_MASTER_GAIN;
119625ab80dbSSrinivas Kandagatla 	param_data->param_size = payload_size - APM_MODULE_PARAM_DATA_SIZE;
119725ab80dbSSrinivas Kandagatla 
119825ab80dbSSrinivas Kandagatla 	p = p + APM_MODULE_PARAM_DATA_SIZE;
119925ab80dbSSrinivas Kandagatla 	cfg = p;
120025ab80dbSSrinivas Kandagatla 	cfg->master_gain =  vol;
120125ab80dbSSrinivas Kandagatla 	rc = q6apm_send_cmd_sync(apm, pkt, 0);
120225ab80dbSSrinivas Kandagatla 
120325ab80dbSSrinivas Kandagatla 	kfree(pkt);
120425ab80dbSSrinivas Kandagatla 
120525ab80dbSSrinivas Kandagatla 	return rc;
120625ab80dbSSrinivas Kandagatla }
120725ab80dbSSrinivas Kandagatla EXPORT_SYMBOL_GPL(audioreach_gain_set_vol_ctrl);
120825ab80dbSSrinivas Kandagatla 
audioreach_gain_set(struct q6apm_graph * graph,struct audioreach_module * module)120925ab80dbSSrinivas Kandagatla static int audioreach_gain_set(struct q6apm_graph *graph, struct audioreach_module *module)
121025ab80dbSSrinivas Kandagatla {
121125ab80dbSSrinivas Kandagatla 	struct apm_module_param_data *param_data;
121225ab80dbSSrinivas Kandagatla 	struct apm_gain_module_cfg *cfg;
121325ab80dbSSrinivas Kandagatla 	int rc, payload_size;
121425ab80dbSSrinivas Kandagatla 	struct gpr_pkt *pkt;
121525ab80dbSSrinivas Kandagatla 
121625ab80dbSSrinivas Kandagatla 	payload_size = APM_GAIN_CFG_PSIZE;
121725ab80dbSSrinivas Kandagatla 	pkt = audioreach_alloc_apm_cmd_pkt(payload_size, APM_CMD_SET_CFG, 0);
121825ab80dbSSrinivas Kandagatla 	if (IS_ERR(pkt))
121925ab80dbSSrinivas Kandagatla 		return PTR_ERR(pkt);
122025ab80dbSSrinivas Kandagatla 
122125ab80dbSSrinivas Kandagatla 	cfg = (void *)pkt + GPR_HDR_SIZE + APM_CMD_HDR_SIZE;
122225ab80dbSSrinivas Kandagatla 
122325ab80dbSSrinivas Kandagatla 	param_data = &cfg->param_data;
122425ab80dbSSrinivas Kandagatla 	param_data->module_instance_id = module->instance_id;
122525ab80dbSSrinivas Kandagatla 	param_data->error_code = 0;
122625ab80dbSSrinivas Kandagatla 	param_data->param_id = APM_PARAM_ID_GAIN;
122725ab80dbSSrinivas Kandagatla 	param_data->param_size = payload_size - APM_MODULE_PARAM_DATA_SIZE;
122825ab80dbSSrinivas Kandagatla 
122925ab80dbSSrinivas Kandagatla 	cfg->gain_cfg.gain = module->gain;
123025ab80dbSSrinivas Kandagatla 
123125ab80dbSSrinivas Kandagatla 	rc = q6apm_send_cmd_sync(graph->apm, pkt, 0);
123225ab80dbSSrinivas Kandagatla 
123325ab80dbSSrinivas Kandagatla 	kfree(pkt);
123425ab80dbSSrinivas Kandagatla 
123525ab80dbSSrinivas Kandagatla 	return rc;
123625ab80dbSSrinivas Kandagatla }
123725ab80dbSSrinivas Kandagatla 
audioreach_set_media_format(struct q6apm_graph * graph,struct audioreach_module * module,struct audioreach_module_config * cfg)123825ab80dbSSrinivas Kandagatla int audioreach_set_media_format(struct q6apm_graph *graph, struct audioreach_module *module,
123925ab80dbSSrinivas Kandagatla 				struct audioreach_module_config *cfg)
124025ab80dbSSrinivas Kandagatla {
124125ab80dbSSrinivas Kandagatla 	int rc;
124225ab80dbSSrinivas Kandagatla 
124325ab80dbSSrinivas Kandagatla 	switch (module->module_id) {
124425ab80dbSSrinivas Kandagatla 	case MODULE_ID_DATA_LOGGING:
12456648a6dcSSrinivas Kandagatla 		rc = audioreach_module_enable(graph, module, true);
12466648a6dcSSrinivas Kandagatla 		if (!rc)
124725ab80dbSSrinivas Kandagatla 			rc = audioreach_logging_set_media_format(graph, module);
124825ab80dbSSrinivas Kandagatla 		break;
124925ab80dbSSrinivas Kandagatla 	case MODULE_ID_PCM_DEC:
125025ab80dbSSrinivas Kandagatla 	case MODULE_ID_PCM_ENC:
125125ab80dbSSrinivas Kandagatla 	case MODULE_ID_PCM_CNV:
1252c7548f59SSrinivas Kandagatla 	case MODULE_ID_PLACEHOLDER_DECODER:
1253c7548f59SSrinivas Kandagatla 	case MODULE_ID_PLACEHOLDER_ENCODER:
125425ab80dbSSrinivas Kandagatla 		rc = audioreach_pcm_set_media_format(graph, module, cfg);
125525ab80dbSSrinivas Kandagatla 		break;
1256a8ab6541SSrinivas Kandagatla 	case MODULE_ID_DISPLAY_PORT_SINK:
1257a8ab6541SSrinivas Kandagatla 		rc = audioreach_display_port_set_media_format(graph, module, cfg);
1258a8ab6541SSrinivas Kandagatla 		break;
125925ab80dbSSrinivas Kandagatla 	case MODULE_ID_I2S_SOURCE:
126025ab80dbSSrinivas Kandagatla 	case MODULE_ID_I2S_SINK:
126125ab80dbSSrinivas Kandagatla 		rc = audioreach_i2s_set_media_format(graph, module, cfg);
126225ab80dbSSrinivas Kandagatla 		break;
126325ab80dbSSrinivas Kandagatla 	case MODULE_ID_WR_SHARED_MEM_EP:
126425ab80dbSSrinivas Kandagatla 		rc = audioreach_shmem_set_media_format(graph, module, cfg);
126525ab80dbSSrinivas Kandagatla 		break;
126625ab80dbSSrinivas Kandagatla 	case MODULE_ID_GAIN:
126725ab80dbSSrinivas Kandagatla 		rc = audioreach_gain_set(graph, module);
126825ab80dbSSrinivas Kandagatla 		break;
126925ab80dbSSrinivas Kandagatla 	case MODULE_ID_CODEC_DMA_SINK:
127025ab80dbSSrinivas Kandagatla 	case MODULE_ID_CODEC_DMA_SOURCE:
127125ab80dbSSrinivas Kandagatla 		rc = audioreach_codec_dma_set_media_format(graph, module, cfg);
127225ab80dbSSrinivas Kandagatla 		break;
1273a934afdbSSrinivas Kandagatla 	case MODULE_ID_SAL:
1274a934afdbSSrinivas Kandagatla 		rc = audioreach_sal_set_media_format(graph, module, cfg);
1275a934afdbSSrinivas Kandagatla 		if (!rc)
1276a934afdbSSrinivas Kandagatla 			rc = audioreach_sal_limiter_enable(graph, module, true);
1277a934afdbSSrinivas Kandagatla 		break;
1278cf0de67dSSrinivas Kandagatla 	case MODULE_ID_MFC:
1279cf0de67dSSrinivas Kandagatla 		rc = audioreach_mfc_set_media_format(graph, module, cfg);
1280cf0de67dSSrinivas Kandagatla 		break;
1281*2c954a37SMohammad Rafi Shaik 	case MODULE_ID_GAPLESS:
1282*2c954a37SMohammad Rafi Shaik 		rc = audioreach_gapless_set_media_format(graph, module, cfg);
1283*2c954a37SMohammad Rafi Shaik 		break;
128425ab80dbSSrinivas Kandagatla 	default:
128525ab80dbSSrinivas Kandagatla 		rc = 0;
128625ab80dbSSrinivas Kandagatla 	}
128725ab80dbSSrinivas Kandagatla 
128825ab80dbSSrinivas Kandagatla 	return rc;
128925ab80dbSSrinivas Kandagatla }
129025ab80dbSSrinivas Kandagatla EXPORT_SYMBOL_GPL(audioreach_set_media_format);
129125ab80dbSSrinivas Kandagatla 
audioreach_graph_free_buf(struct q6apm_graph * graph)129225ab80dbSSrinivas Kandagatla void audioreach_graph_free_buf(struct q6apm_graph *graph)
129325ab80dbSSrinivas Kandagatla {
129425ab80dbSSrinivas Kandagatla 	struct audioreach_graph_data *port;
129525ab80dbSSrinivas Kandagatla 
129625ab80dbSSrinivas Kandagatla 	mutex_lock(&graph->lock);
129725ab80dbSSrinivas Kandagatla 	port = &graph->rx_data;
129825ab80dbSSrinivas Kandagatla 	port->num_periods = 0;
129925ab80dbSSrinivas Kandagatla 	kfree(port->buf);
130025ab80dbSSrinivas Kandagatla 	port->buf = NULL;
130125ab80dbSSrinivas Kandagatla 
130225ab80dbSSrinivas Kandagatla 	port = &graph->tx_data;
130325ab80dbSSrinivas Kandagatla 	port->num_periods = 0;
130425ab80dbSSrinivas Kandagatla 	kfree(port->buf);
130525ab80dbSSrinivas Kandagatla 	port->buf = NULL;
130625ab80dbSSrinivas Kandagatla 	mutex_unlock(&graph->lock);
130725ab80dbSSrinivas Kandagatla }
130825ab80dbSSrinivas Kandagatla EXPORT_SYMBOL_GPL(audioreach_graph_free_buf);
130925ab80dbSSrinivas Kandagatla 
audioreach_map_memory_regions(struct q6apm_graph * graph,unsigned int dir,size_t period_sz,unsigned int periods,bool is_contiguous)131025ab80dbSSrinivas Kandagatla int audioreach_map_memory_regions(struct q6apm_graph *graph, unsigned int dir, size_t period_sz,
131125ab80dbSSrinivas Kandagatla 				  unsigned int periods, bool is_contiguous)
131225ab80dbSSrinivas Kandagatla {
131325ab80dbSSrinivas Kandagatla 	struct apm_shared_map_region_payload *mregions;
131425ab80dbSSrinivas Kandagatla 	struct apm_cmd_shared_mem_map_regions *cmd;
131525ab80dbSSrinivas Kandagatla 	uint32_t num_regions, buf_sz, payload_size;
131625ab80dbSSrinivas Kandagatla 	struct audioreach_graph_data *data;
131725ab80dbSSrinivas Kandagatla 	struct gpr_pkt *pkt;
131825ab80dbSSrinivas Kandagatla 	void *p;
131925ab80dbSSrinivas Kandagatla 	int rc, i;
132025ab80dbSSrinivas Kandagatla 
132125ab80dbSSrinivas Kandagatla 	if (dir == SNDRV_PCM_STREAM_PLAYBACK)
132225ab80dbSSrinivas Kandagatla 		data = &graph->rx_data;
132325ab80dbSSrinivas Kandagatla 	else
132425ab80dbSSrinivas Kandagatla 		data = &graph->tx_data;
132525ab80dbSSrinivas Kandagatla 
132625ab80dbSSrinivas Kandagatla 	if (is_contiguous) {
132725ab80dbSSrinivas Kandagatla 		num_regions = 1;
132825ab80dbSSrinivas Kandagatla 		buf_sz = period_sz * periods;
132925ab80dbSSrinivas Kandagatla 	} else {
133025ab80dbSSrinivas Kandagatla 		buf_sz = period_sz;
133125ab80dbSSrinivas Kandagatla 		num_regions = periods;
133225ab80dbSSrinivas Kandagatla 	}
133325ab80dbSSrinivas Kandagatla 
133425ab80dbSSrinivas Kandagatla 	/* DSP expects size should be aligned to 4K */
133525ab80dbSSrinivas Kandagatla 	buf_sz = ALIGN(buf_sz, 4096);
133625ab80dbSSrinivas Kandagatla 
133725ab80dbSSrinivas Kandagatla 	payload_size = sizeof(*cmd) + (sizeof(*mregions) * num_regions);
133825ab80dbSSrinivas Kandagatla 
133925ab80dbSSrinivas Kandagatla 	pkt = audioreach_alloc_apm_pkt(payload_size, APM_CMD_SHARED_MEM_MAP_REGIONS, dir,
134025ab80dbSSrinivas Kandagatla 				     graph->port->id);
134125ab80dbSSrinivas Kandagatla 	if (IS_ERR(pkt))
134225ab80dbSSrinivas Kandagatla 		return PTR_ERR(pkt);
134325ab80dbSSrinivas Kandagatla 
134425ab80dbSSrinivas Kandagatla 	p = (void *)pkt + GPR_HDR_SIZE;
134525ab80dbSSrinivas Kandagatla 	cmd = p;
134625ab80dbSSrinivas Kandagatla 	cmd->mem_pool_id = APM_MEMORY_MAP_SHMEM8_4K_POOL;
134725ab80dbSSrinivas Kandagatla 	cmd->num_regions = num_regions;
134825ab80dbSSrinivas Kandagatla 
134925ab80dbSSrinivas Kandagatla 	cmd->property_flag = 0x0;
135025ab80dbSSrinivas Kandagatla 
135125ab80dbSSrinivas Kandagatla 	mregions = p + sizeof(*cmd);
135225ab80dbSSrinivas Kandagatla 
135325ab80dbSSrinivas Kandagatla 	mutex_lock(&graph->lock);
135425ab80dbSSrinivas Kandagatla 
135525ab80dbSSrinivas Kandagatla 	for (i = 0; i < num_regions; i++) {
135625ab80dbSSrinivas Kandagatla 		struct audio_buffer *ab;
135725ab80dbSSrinivas Kandagatla 
135825ab80dbSSrinivas Kandagatla 		ab = &data->buf[i];
135925ab80dbSSrinivas Kandagatla 		mregions->shm_addr_lsw = lower_32_bits(ab->phys);
136025ab80dbSSrinivas Kandagatla 		mregions->shm_addr_msw = upper_32_bits(ab->phys);
136125ab80dbSSrinivas Kandagatla 		mregions->mem_size_bytes = buf_sz;
136225ab80dbSSrinivas Kandagatla 		++mregions;
136325ab80dbSSrinivas Kandagatla 	}
136425ab80dbSSrinivas Kandagatla 	mutex_unlock(&graph->lock);
136525ab80dbSSrinivas Kandagatla 
136625ab80dbSSrinivas Kandagatla 	rc = audioreach_graph_send_cmd_sync(graph, pkt, APM_CMD_RSP_SHARED_MEM_MAP_REGIONS);
136725ab80dbSSrinivas Kandagatla 
136825ab80dbSSrinivas Kandagatla 	kfree(pkt);
136925ab80dbSSrinivas Kandagatla 
137025ab80dbSSrinivas Kandagatla 	return rc;
137125ab80dbSSrinivas Kandagatla }
137225ab80dbSSrinivas Kandagatla EXPORT_SYMBOL_GPL(audioreach_map_memory_regions);
137325ab80dbSSrinivas Kandagatla 
audioreach_shared_memory_send_eos(struct q6apm_graph * graph)137425ab80dbSSrinivas Kandagatla int audioreach_shared_memory_send_eos(struct q6apm_graph *graph)
137525ab80dbSSrinivas Kandagatla {
137625ab80dbSSrinivas Kandagatla 	struct data_cmd_wr_sh_mem_ep_eos *eos;
137725ab80dbSSrinivas Kandagatla 	struct gpr_pkt *pkt;
137825ab80dbSSrinivas Kandagatla 	int rc = 0, iid;
137925ab80dbSSrinivas Kandagatla 
138025ab80dbSSrinivas Kandagatla 	iid = q6apm_graph_get_rx_shmem_module_iid(graph);
138125ab80dbSSrinivas Kandagatla 	pkt = audioreach_alloc_cmd_pkt(sizeof(*eos), DATA_CMD_WR_SH_MEM_EP_EOS, 0,
138225ab80dbSSrinivas Kandagatla 				       graph->port->id, iid);
138325ab80dbSSrinivas Kandagatla 	if (IS_ERR(pkt))
138425ab80dbSSrinivas Kandagatla 		return PTR_ERR(pkt);
138525ab80dbSSrinivas Kandagatla 
138625ab80dbSSrinivas Kandagatla 	eos = (void *)pkt + GPR_HDR_SIZE + APM_CMD_HDR_SIZE;
138725ab80dbSSrinivas Kandagatla 
138825ab80dbSSrinivas Kandagatla 	eos->policy = WR_SH_MEM_EP_EOS_POLICY_LAST;
138925ab80dbSSrinivas Kandagatla 
139025ab80dbSSrinivas Kandagatla 	rc = gpr_send_port_pkt(graph->port, pkt);
139125ab80dbSSrinivas Kandagatla 	kfree(pkt);
139225ab80dbSSrinivas Kandagatla 
139325ab80dbSSrinivas Kandagatla 	return rc;
139425ab80dbSSrinivas Kandagatla }
139525ab80dbSSrinivas Kandagatla EXPORT_SYMBOL_GPL(audioreach_shared_memory_send_eos);
1396