1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2020, Linaro Limited
4 #include <linux/kernel.h>
5 #include <linux/slab.h>
6 #include <linux/soc/qcom/apr.h>
8 #include <sound/soc-dai.h>
10 #include <sound/pcm_params.h>
11 #include <dt-bindings/soc/qcom,gpr.h>
13 #include "audioreach.h"
16 struct apm_sub_graph_data
{
17 struct apm_sub_graph_cfg sub_graph_cfg
;
18 struct apm_prop_data perf_data
;
19 struct apm_sg_prop_id_perf_mode perf
;
20 struct apm_prop_data dir_data
;
21 struct apm_sg_prop_id_direction dir
;
22 struct apm_prop_data sid_data
;
23 struct apm_sg_prop_id_scenario_id sid
;
27 #define APM_SUB_GRAPH_CFG_NPROP 3
29 struct apm_sub_graph_params
{
30 struct apm_module_param_data param_data
;
31 uint32_t num_sub_graphs
;
32 struct apm_sub_graph_data sg_cfg
[];
35 #define APM_SUB_GRAPH_PSIZE(p, n) ALIGN(struct_size(p, sg_cfg, n), 8)
37 /* container config */
38 struct apm_container_obj
{
39 struct apm_container_cfg container_cfg
;
40 /* Capability ID list */
41 struct apm_prop_data cap_data
;
42 uint32_t num_capability_id
;
43 uint32_t capability_id
;
45 /* Container graph Position */
46 struct apm_prop_data pos_data
;
47 struct apm_cont_prop_id_graph_pos pos
;
49 /* Container Stack size */
50 struct apm_prop_data stack_data
;
51 struct apm_cont_prop_id_stack_size stack
;
53 /* Container proc domain id */
54 struct apm_prop_data domain_data
;
55 struct apm_cont_prop_id_domain domain
;
58 struct apm_container_params
{
59 struct apm_module_param_data param_data
;
60 uint32_t num_containers
;
61 struct apm_container_obj cont_obj
[];
64 #define APM_CONTAINER_PSIZE(p, n) ALIGN(struct_size(p, cont_obj, n), 8)
66 /* Module List config */
67 struct apm_mod_list_obj
{
68 /* Modules list cfg */
69 uint32_t sub_graph_id
;
70 uint32_t container_id
;
72 struct apm_module_obj mod_cfg
[];
75 #define APM_MOD_LIST_OBJ_PSIZE(p, n) struct_size(p, mod_cfg, n)
77 struct apm_module_list_params
{
78 struct apm_module_param_data param_data
;
79 uint32_t num_modules_list
;
80 /* Module list config array */
81 struct apm_mod_list_obj mod_list_obj
[];
85 /* Module Properties */
86 struct apm_mod_prop_obj
{
89 struct apm_prop_data prop_data_1
;
90 struct apm_module_prop_id_port_info prop_id_port
;
93 struct apm_prop_list_params
{
94 struct apm_module_param_data param_data
;
95 u32 num_modules_prop_cfg
;
96 struct apm_mod_prop_obj mod_prop_obj
[];
100 #define APM_MOD_PROP_PSIZE(p, n) ALIGN(struct_size(p, mod_prop_obj, n), 8)
102 /* Module Connections */
103 struct apm_mod_conn_list_params
{
104 struct apm_module_param_data param_data
;
106 struct apm_module_conn_obj conn_obj
[];
110 #define APM_MOD_CONN_PSIZE(p, n) ALIGN(struct_size(p, conn_obj, n), 8)
112 struct apm_graph_open_params
{
113 struct apm_cmd_header
*cmd_header
;
114 struct apm_sub_graph_params
*sg_data
;
115 struct apm_container_params
*cont_data
;
116 struct apm_module_list_params
*mod_list_data
;
117 struct apm_prop_list_params
*mod_prop_data
;
118 struct apm_mod_conn_list_params
*mod_conn_list_data
;
121 struct apm_pcm_module_media_fmt_cmd
{
122 struct apm_module_param_data param_data
;
123 struct param_id_pcm_output_format_cfg header
;
124 struct payload_pcm_output_format_cfg media_cfg
;
127 struct apm_rd_shmem_module_config_cmd
{
128 struct apm_module_param_data param_data
;
129 struct param_id_rd_sh_mem_cfg cfg
;
132 struct apm_sh_module_media_fmt_cmd
{
133 struct media_format header
;
134 struct payload_media_fmt_pcm cfg
;
137 #define APM_SHMEM_FMT_CFG_PSIZE(ch) ALIGN( \
138 sizeof(struct apm_sh_module_media_fmt_cmd) + \
139 ch * sizeof(uint8_t), 8)
141 /* num of channels as argument */
142 #define APM_PCM_MODULE_FMT_CMD_PSIZE(ch) ALIGN( \
143 sizeof(struct apm_pcm_module_media_fmt_cmd) + \
144 ch * sizeof(uint8_t), 8)
146 #define APM_PCM_OUT_FMT_CFG_PSIZE(p, n) ALIGN(struct_size(p, channel_mapping, n), 4)
148 struct apm_i2s_module_intf_cfg
{
149 struct apm_module_param_data param_data
;
150 struct param_id_i2s_intf_cfg cfg
;
153 #define APM_I2S_INTF_CFG_PSIZE ALIGN(sizeof(struct apm_i2s_module_intf_cfg), 8)
155 struct apm_module_hw_ep_mf_cfg
{
156 struct apm_module_param_data param_data
;
157 struct param_id_hw_ep_mf mf
;
160 #define APM_HW_EP_CFG_PSIZE ALIGN(sizeof(struct apm_module_hw_ep_mf_cfg), 8)
162 #define APM_MFC_CFG_PSIZE(p, n) ALIGN(struct_size(p, channel_mapping, n), 4)
164 struct apm_module_frame_size_factor_cfg
{
165 struct apm_module_param_data param_data
;
166 uint32_t frame_size_factor
;
169 #define APM_FS_CFG_PSIZE ALIGN(sizeof(struct apm_module_frame_size_factor_cfg), 8)
171 struct apm_module_hw_ep_power_mode_cfg
{
172 struct apm_module_param_data param_data
;
173 struct param_id_hw_ep_power_mode_cfg power_mode
;
176 #define APM_HW_EP_PMODE_CFG_PSIZE ALIGN(sizeof(struct apm_module_hw_ep_power_mode_cfg), 8)
178 struct apm_module_hw_ep_dma_data_align_cfg
{
179 struct apm_module_param_data param_data
;
180 struct param_id_hw_ep_dma_data_align align
;
183 #define APM_HW_EP_DALIGN_CFG_PSIZE ALIGN(sizeof(struct apm_module_hw_ep_dma_data_align_cfg), 8)
185 struct apm_gain_module_cfg
{
186 struct apm_module_param_data param_data
;
187 struct param_id_gain_cfg gain_cfg
;
190 #define APM_GAIN_CFG_PSIZE ALIGN(sizeof(struct apm_gain_module_cfg), 8)
192 struct apm_codec_dma_module_intf_cfg
{
193 struct apm_module_param_data param_data
;
194 struct param_id_codec_dma_intf_cfg cfg
;
197 #define APM_CDMA_INTF_CFG_PSIZE ALIGN(sizeof(struct apm_codec_dma_module_intf_cfg), 8)
199 struct apm_display_port_module_intf_cfg
{
200 struct apm_module_param_data param_data
;
201 struct param_id_display_port_intf_cfg cfg
;
203 #define APM_DP_INTF_CFG_PSIZE ALIGN(sizeof(struct apm_display_port_module_intf_cfg), 8)
205 static void *__audioreach_alloc_pkt(int payload_size
, uint32_t opcode
, uint32_t token
,
206 uint32_t src_port
, uint32_t dest_port
, bool has_cmd_hdr
)
210 int pkt_size
= GPR_HDR_SIZE
+ payload_size
;
213 pkt_size
+= APM_CMD_HDR_SIZE
;
215 p
= kzalloc(pkt_size
, GFP_KERNEL
);
217 return ERR_PTR(-ENOMEM
);
220 pkt
->hdr
.version
= GPR_PKT_VER
;
221 pkt
->hdr
.hdr_size
= GPR_PKT_HEADER_WORD_SIZE
;
222 pkt
->hdr
.pkt_size
= pkt_size
;
223 pkt
->hdr
.dest_port
= dest_port
;
224 pkt
->hdr
.src_port
= src_port
;
226 pkt
->hdr
.dest_domain
= GPR_DOMAIN_ID_ADSP
;
227 pkt
->hdr
.src_domain
= GPR_DOMAIN_ID_APPS
;
228 pkt
->hdr
.token
= token
;
229 pkt
->hdr
.opcode
= opcode
;
232 struct apm_cmd_header
*cmd_header
;
234 p
= p
+ GPR_HDR_SIZE
;
236 cmd_header
->payload_size
= payload_size
;
242 void *audioreach_alloc_pkt(int payload_size
, uint32_t opcode
, uint32_t token
,
243 uint32_t src_port
, uint32_t dest_port
)
245 return __audioreach_alloc_pkt(payload_size
, opcode
, token
, src_port
, dest_port
, false);
247 EXPORT_SYMBOL_GPL(audioreach_alloc_pkt
);
249 void *audioreach_alloc_apm_pkt(int pkt_size
, uint32_t opcode
, uint32_t token
, uint32_t src_port
)
251 return __audioreach_alloc_pkt(pkt_size
, opcode
, token
, src_port
, APM_MODULE_INSTANCE_ID
,
254 EXPORT_SYMBOL_GPL(audioreach_alloc_apm_pkt
);
256 void *audioreach_alloc_cmd_pkt(int payload_size
, uint32_t opcode
, uint32_t token
,
257 uint32_t src_port
, uint32_t dest_port
)
259 return __audioreach_alloc_pkt(payload_size
, opcode
, token
, src_port
, dest_port
, true);
261 EXPORT_SYMBOL_GPL(audioreach_alloc_cmd_pkt
);
263 void *audioreach_alloc_apm_cmd_pkt(int pkt_size
, uint32_t opcode
, uint32_t token
)
265 return __audioreach_alloc_pkt(pkt_size
, opcode
, token
, GPR_APM_MODULE_IID
,
266 APM_MODULE_INSTANCE_ID
, true);
268 EXPORT_SYMBOL_GPL(audioreach_alloc_apm_cmd_pkt
);
270 void audioreach_set_default_channel_mapping(u8
*ch_map
, int num_channels
)
272 if (num_channels
== 1) {
273 ch_map
[0] = PCM_CHANNEL_FL
;
274 } else if (num_channels
== 2) {
275 ch_map
[0] = PCM_CHANNEL_FL
;
276 ch_map
[1] = PCM_CHANNEL_FR
;
277 } else if (num_channels
== 4) {
278 ch_map
[0] = PCM_CHANNEL_FL
;
279 ch_map
[1] = PCM_CHANNEL_FR
;
280 ch_map
[2] = PCM_CHANNEL_LS
;
281 ch_map
[3] = PCM_CHANNEL_RS
;
284 EXPORT_SYMBOL_GPL(audioreach_set_default_channel_mapping
);
286 static void apm_populate_container_config(struct apm_container_obj
*cfg
,
287 struct audioreach_container
*cont
)
290 /* Container Config */
291 cfg
->container_cfg
.container_id
= cont
->container_id
;
292 cfg
->container_cfg
.num_prop
= 4;
294 /* Capability list */
295 cfg
->cap_data
.prop_id
= APM_CONTAINER_PROP_ID_CAPABILITY_LIST
;
296 cfg
->cap_data
.prop_size
= APM_CONTAINER_PROP_ID_CAPABILITY_SIZE
;
297 cfg
->num_capability_id
= 1;
298 cfg
->capability_id
= cont
->capability_id
;
301 cfg
->pos_data
.prop_id
= APM_CONTAINER_PROP_ID_GRAPH_POS
;
302 cfg
->pos_data
.prop_size
= sizeof(struct apm_cont_prop_id_graph_pos
);
303 cfg
->pos
.graph_pos
= cont
->graph_pos
;
306 cfg
->stack_data
.prop_id
= APM_CONTAINER_PROP_ID_STACK_SIZE
;
307 cfg
->stack_data
.prop_size
= sizeof(struct apm_cont_prop_id_stack_size
);
308 cfg
->stack
.stack_size
= cont
->stack_size
;
311 cfg
->domain_data
.prop_id
= APM_CONTAINER_PROP_ID_PROC_DOMAIN
;
312 cfg
->domain_data
.prop_size
= sizeof(struct apm_cont_prop_id_domain
);
313 cfg
->domain
.proc_domain
= cont
->proc_domain
;
316 static void apm_populate_sub_graph_config(struct apm_sub_graph_data
*cfg
,
317 struct audioreach_sub_graph
*sg
)
319 cfg
->sub_graph_cfg
.sub_graph_id
= sg
->sub_graph_id
;
320 cfg
->sub_graph_cfg
.num_sub_graph_prop
= APM_SUB_GRAPH_CFG_NPROP
;
323 cfg
->perf_data
.prop_id
= APM_SUB_GRAPH_PROP_ID_PERF_MODE
;
324 cfg
->perf_data
.prop_size
= APM_SG_PROP_ID_PERF_MODE_SIZE
;
325 cfg
->perf
.perf_mode
= sg
->perf_mode
;
328 cfg
->dir_data
.prop_id
= APM_SUB_GRAPH_PROP_ID_DIRECTION
;
329 cfg
->dir_data
.prop_size
= APM_SG_PROP_ID_DIR_SIZE
;
330 cfg
->dir
.direction
= sg
->direction
;
333 cfg
->sid_data
.prop_id
= APM_SUB_GRAPH_PROP_ID_SCENARIO_ID
;
334 cfg
->sid_data
.prop_size
= APM_SG_PROP_ID_SID_SIZE
;
335 cfg
->sid
.scenario_id
= sg
->scenario_id
;
338 static void apm_populate_module_prop_obj(struct apm_mod_prop_obj
*obj
,
339 struct audioreach_module
*module
)
342 obj
->instance_id
= module
->instance_id
;
344 obj
->prop_data_1
.prop_id
= APM_MODULE_PROP_ID_PORT_INFO
;
345 obj
->prop_data_1
.prop_size
= APM_MODULE_PROP_ID_PORT_INFO_SZ
;
346 obj
->prop_id_port
.max_ip_port
= module
->max_ip_port
;
347 obj
->prop_id_port
.max_op_port
= module
->max_op_port
;
350 static void apm_populate_module_list_obj(struct apm_mod_list_obj
*obj
,
351 struct audioreach_container
*container
,
354 struct audioreach_module
*module
;
357 obj
->sub_graph_id
= sub_graph_id
;
358 obj
->container_id
= container
->container_id
;
359 obj
->num_modules
= container
->num_modules
;
361 list_for_each_entry(module
, &container
->modules_list
, node
) {
362 obj
->mod_cfg
[i
].module_id
= module
->module_id
;
363 obj
->mod_cfg
[i
].instance_id
= module
->instance_id
;
368 static void audioreach_populate_graph(struct q6apm
*apm
, struct audioreach_graph_info
*info
,
369 struct apm_graph_open_params
*open
,
370 struct list_head
*sg_list
,
373 struct apm_mod_conn_list_params
*mc_data
= open
->mod_conn_list_data
;
374 struct apm_module_list_params
*ml_data
= open
->mod_list_data
;
375 struct apm_prop_list_params
*mp_data
= open
->mod_prop_data
;
376 struct apm_container_params
*c_data
= open
->cont_data
;
377 struct apm_sub_graph_params
*sg_data
= open
->sg_data
;
378 int ncontainer
= 0, nmodule
= 0, nconn
= 0;
379 struct apm_mod_prop_obj
*module_prop_obj
;
380 struct audioreach_container
*container
;
381 struct apm_module_conn_obj
*conn_obj
;
382 struct audioreach_module
*module
;
383 struct audioreach_sub_graph
*sg
;
384 struct apm_container_obj
*cobj
;
385 struct apm_mod_list_obj
*mlobj
;
388 mlobj
= &ml_data
->mod_list_obj
[0];
391 if (info
->dst_mod_inst_id
&& info
->src_mod_inst_id
) {
392 conn_obj
= &mc_data
->conn_obj
[nconn
];
393 conn_obj
->src_mod_inst_id
= info
->src_mod_inst_id
;
394 conn_obj
->src_mod_op_port_id
= info
->src_mod_op_port_id
;
395 conn_obj
->dst_mod_inst_id
= info
->dst_mod_inst_id
;
396 conn_obj
->dst_mod_ip_port_id
= info
->dst_mod_ip_port_id
;
400 list_for_each_entry(sg
, sg_list
, node
) {
401 struct apm_sub_graph_data
*sg_cfg
= &sg_data
->sg_cfg
[i
++];
403 apm_populate_sub_graph_config(sg_cfg
, sg
);
405 list_for_each_entry(container
, &sg
->container_list
, node
) {
406 cobj
= &c_data
->cont_obj
[ncontainer
];
408 apm_populate_container_config(cobj
, container
);
409 apm_populate_module_list_obj(mlobj
, container
, sg
->sub_graph_id
);
411 list_for_each_entry(module
, &container
->modules_list
, node
) {
414 module_prop_obj
= &mp_data
->mod_prop_obj
[nmodule
++];
415 apm_populate_module_prop_obj(module_prop_obj
, module
);
417 if (!module
->max_op_port
)
420 for (pn
= 0; pn
< module
->max_op_port
; pn
++) {
421 if (module
->dst_mod_inst_id
[pn
]) {
422 conn_obj
= &mc_data
->conn_obj
[nconn
];
423 conn_obj
->src_mod_inst_id
= module
->instance_id
;
424 conn_obj
->src_mod_op_port_id
=
425 module
->src_mod_op_port_id
[pn
];
426 conn_obj
->dst_mod_inst_id
=
427 module
->dst_mod_inst_id
[pn
];
428 conn_obj
->dst_mod_ip_port_id
=
429 module
->dst_mod_ip_port_id
[pn
];
434 mlobj
= (void *) mlobj
+ APM_MOD_LIST_OBJ_PSIZE(mlobj
,
435 container
->num_modules
);
442 void *audioreach_alloc_graph_pkt(struct q6apm
*apm
, struct audioreach_graph_info
*info
)
444 int payload_size
, sg_sz
, cont_sz
, ml_sz
, mp_sz
, mc_sz
;
445 struct apm_module_param_data
*param_data
;
446 struct apm_container_params
*cont_params
;
447 struct audioreach_container
*container
;
448 struct apm_sub_graph_params
*sg_params
;
449 struct apm_mod_conn_list_params
*mcon
;
450 struct apm_graph_open_params params
;
451 struct apm_prop_list_params
*mprop
;
452 struct audioreach_module
*module
;
453 struct audioreach_sub_graph
*sgs
;
454 struct apm_mod_list_obj
*mlobj
;
455 struct list_head
*sg_list
;
456 int num_connections
= 0;
457 int num_containers
= 0;
458 int num_sub_graphs
= 0;
460 int num_modules_list
;
464 sg_list
= &info
->sg_list
;
467 /* add FE-BE connections */
468 if (info
->dst_mod_inst_id
&& info
->src_mod_inst_id
)
471 list_for_each_entry(sgs
, sg_list
, node
) {
473 list_for_each_entry(container
, &sgs
->container_list
, node
) {
475 num_modules
+= container
->num_modules
;
476 ml_sz
= ml_sz
+ sizeof(struct apm_module_list_params
) +
477 APM_MOD_LIST_OBJ_PSIZE(mlobj
, container
->num_modules
);
479 list_for_each_entry(module
, &container
->modules_list
, node
) {
480 num_connections
+= module
->num_connections
;
485 num_modules_list
= num_containers
;
486 sg_sz
= APM_SUB_GRAPH_PSIZE(sg_params
, num_sub_graphs
);
487 cont_sz
= APM_CONTAINER_PSIZE(cont_params
, num_containers
);
489 ml_sz
= ALIGN(ml_sz
, 8);
491 mp_sz
= APM_MOD_PROP_PSIZE(mprop
, num_modules
);
492 mc_sz
= APM_MOD_CONN_PSIZE(mcon
, num_connections
);
494 payload_size
= sg_sz
+ cont_sz
+ ml_sz
+ mp_sz
+ mc_sz
;
495 pkt
= audioreach_alloc_apm_cmd_pkt(payload_size
, APM_CMD_GRAPH_OPEN
, 0);
499 p
= (void *)pkt
+ GPR_HDR_SIZE
+ APM_CMD_HDR_SIZE
;
503 param_data
= ¶ms
.sg_data
->param_data
;
504 param_data
->module_instance_id
= APM_MODULE_INSTANCE_ID
;
505 param_data
->param_id
= APM_PARAM_ID_SUB_GRAPH_CONFIG
;
506 param_data
->param_size
= sg_sz
- APM_MODULE_PARAM_DATA_SIZE
;
507 params
.sg_data
->num_sub_graphs
= num_sub_graphs
;
511 params
.cont_data
= p
;
512 param_data
= ¶ms
.cont_data
->param_data
;
513 param_data
->module_instance_id
= APM_MODULE_INSTANCE_ID
;
514 param_data
->param_id
= APM_PARAM_ID_CONTAINER_CONFIG
;
515 param_data
->param_size
= cont_sz
- APM_MODULE_PARAM_DATA_SIZE
;
516 params
.cont_data
->num_containers
= num_containers
;
520 params
.mod_list_data
= p
;
521 param_data
= ¶ms
.mod_list_data
->param_data
;
522 param_data
->module_instance_id
= APM_MODULE_INSTANCE_ID
;
523 param_data
->param_id
= APM_PARAM_ID_MODULE_LIST
;
524 param_data
->param_size
= ml_sz
- APM_MODULE_PARAM_DATA_SIZE
;
525 params
.mod_list_data
->num_modules_list
= num_modules_list
;
528 /* Module Properties */
529 params
.mod_prop_data
= p
;
530 param_data
= ¶ms
.mod_prop_data
->param_data
;
531 param_data
->module_instance_id
= APM_MODULE_INSTANCE_ID
;
532 param_data
->param_id
= APM_PARAM_ID_MODULE_PROP
;
533 param_data
->param_size
= mp_sz
- APM_MODULE_PARAM_DATA_SIZE
;
534 params
.mod_prop_data
->num_modules_prop_cfg
= num_modules
;
537 /* Module Connections */
538 params
.mod_conn_list_data
= p
;
539 param_data
= ¶ms
.mod_conn_list_data
->param_data
;
540 param_data
->module_instance_id
= APM_MODULE_INSTANCE_ID
;
541 param_data
->param_id
= APM_PARAM_ID_MODULE_CONN
;
542 param_data
->param_size
= mc_sz
- APM_MODULE_PARAM_DATA_SIZE
;
543 params
.mod_conn_list_data
->num_connections
= num_connections
;
546 audioreach_populate_graph(apm
, info
, ¶ms
, sg_list
, num_sub_graphs
);
550 EXPORT_SYMBOL_GPL(audioreach_alloc_graph_pkt
);
552 int audioreach_send_cmd_sync(struct device
*dev
, gpr_device_t
*gdev
,
553 struct gpr_ibasic_rsp_result_t
*result
, struct mutex
*cmd_lock
,
554 gpr_port_t
*port
, wait_queue_head_t
*cmd_wait
,
555 struct gpr_pkt
*pkt
, uint32_t rsp_opcode
)
558 struct gpr_hdr
*hdr
= &pkt
->hdr
;
561 mutex_lock(cmd_lock
);
566 rc
= gpr_send_port_pkt(port
, pkt
);
568 rc
= gpr_send_pkt(gdev
, pkt
);
576 rc
= wait_event_timeout(*cmd_wait
, (result
->opcode
== hdr
->opcode
) ||
577 (result
->opcode
== rsp_opcode
), 5 * HZ
);
579 rc
= wait_event_timeout(*cmd_wait
, (result
->opcode
== hdr
->opcode
), 5 * HZ
);
582 dev_err(dev
, "CMD timeout for [%x] opcode\n", hdr
->opcode
);
584 } else if (result
->status
> 0) {
585 dev_err(dev
, "DSP returned error[%x] %x\n", hdr
->opcode
, result
->status
);
588 /* DSP successfully finished the command */
593 mutex_unlock(cmd_lock
);
596 EXPORT_SYMBOL_GPL(audioreach_send_cmd_sync
);
598 int audioreach_graph_send_cmd_sync(struct q6apm_graph
*graph
, struct gpr_pkt
*pkt
,
602 return audioreach_send_cmd_sync(graph
->dev
, NULL
, &graph
->result
, &graph
->lock
,
603 graph
->port
, &graph
->cmd_wait
, pkt
, rsp_opcode
);
605 EXPORT_SYMBOL_GPL(audioreach_graph_send_cmd_sync
);
607 static int audioreach_display_port_set_media_format(struct q6apm_graph
*graph
,
608 struct audioreach_module
*module
,
609 struct audioreach_module_config
*cfg
)
611 struct apm_display_port_module_intf_cfg
*intf_cfg
;
612 struct apm_module_frame_size_factor_cfg
*fs_cfg
;
613 struct apm_module_param_data
*param_data
;
614 struct apm_module_hw_ep_mf_cfg
*hw_cfg
;
615 int ic_sz
, ep_sz
, fs_sz
, dl_sz
;
616 int rc
, payload_size
;
620 ic_sz
= APM_DP_INTF_CFG_PSIZE
;
621 ep_sz
= APM_HW_EP_CFG_PSIZE
;
622 fs_sz
= APM_FS_CFG_PSIZE
;
625 payload_size
= ic_sz
+ ep_sz
+ fs_sz
+ dl_sz
;
627 pkt
= audioreach_alloc_apm_cmd_pkt(payload_size
, APM_CMD_SET_CFG
, 0);
631 p
= (void *)pkt
+ GPR_HDR_SIZE
+ APM_CMD_HDR_SIZE
;
634 param_data
= &hw_cfg
->param_data
;
635 param_data
->module_instance_id
= module
->instance_id
;
636 param_data
->error_code
= 0;
637 param_data
->param_id
= PARAM_ID_HW_EP_MF_CFG
;
638 param_data
->param_size
= ep_sz
- APM_MODULE_PARAM_DATA_SIZE
;
640 hw_cfg
->mf
.sample_rate
= cfg
->sample_rate
;
641 hw_cfg
->mf
.bit_width
= cfg
->bit_width
;
642 hw_cfg
->mf
.num_channels
= cfg
->num_channels
;
643 hw_cfg
->mf
.data_format
= module
->data_format
;
647 param_data
= &fs_cfg
->param_data
;
648 param_data
->module_instance_id
= module
->instance_id
;
649 param_data
->error_code
= 0;
650 param_data
->param_id
= PARAM_ID_HW_EP_FRAME_SIZE_FACTOR
;
651 param_data
->param_size
= fs_sz
- APM_MODULE_PARAM_DATA_SIZE
;
652 fs_cfg
->frame_size_factor
= 1;
656 param_data
= &intf_cfg
->param_data
;
657 param_data
->module_instance_id
= module
->instance_id
;
658 param_data
->error_code
= 0;
659 param_data
->param_id
= PARAM_ID_DISPLAY_PORT_INTF_CFG
;
660 param_data
->param_size
= ic_sz
- APM_MODULE_PARAM_DATA_SIZE
;
662 intf_cfg
->cfg
.channel_allocation
= cfg
->channel_allocation
;
663 intf_cfg
->cfg
.mst_idx
= 0;
664 intf_cfg
->cfg
.dptx_idx
= cfg
->dp_idx
;
666 rc
= q6apm_send_cmd_sync(graph
->apm
, pkt
, 0);
673 /* LPASS Codec DMA port Module Media Format Setup */
674 static int audioreach_codec_dma_set_media_format(struct q6apm_graph
*graph
,
675 struct audioreach_module
*module
,
676 struct audioreach_module_config
*cfg
)
678 struct apm_codec_dma_module_intf_cfg
*intf_cfg
;
679 struct apm_module_frame_size_factor_cfg
*fs_cfg
;
680 struct apm_module_hw_ep_power_mode_cfg
*pm_cfg
;
681 struct apm_module_param_data
*param_data
;
682 struct apm_module_hw_ep_mf_cfg
*hw_cfg
;
683 int ic_sz
, ep_sz
, fs_sz
, pm_sz
, dl_sz
;
684 int rc
, payload_size
;
688 ic_sz
= APM_CDMA_INTF_CFG_PSIZE
;
689 ep_sz
= APM_HW_EP_CFG_PSIZE
;
690 fs_sz
= APM_FS_CFG_PSIZE
;
691 pm_sz
= APM_HW_EP_PMODE_CFG_PSIZE
;
694 payload_size
= ic_sz
+ ep_sz
+ fs_sz
+ pm_sz
+ dl_sz
;
696 pkt
= audioreach_alloc_apm_cmd_pkt(payload_size
, APM_CMD_SET_CFG
, 0);
700 p
= (void *)pkt
+ GPR_HDR_SIZE
+ APM_CMD_HDR_SIZE
;
703 param_data
= &hw_cfg
->param_data
;
704 param_data
->module_instance_id
= module
->instance_id
;
705 param_data
->error_code
= 0;
706 param_data
->param_id
= PARAM_ID_HW_EP_MF_CFG
;
707 param_data
->param_size
= ep_sz
- APM_MODULE_PARAM_DATA_SIZE
;
709 hw_cfg
->mf
.sample_rate
= cfg
->sample_rate
;
710 hw_cfg
->mf
.bit_width
= cfg
->bit_width
;
711 hw_cfg
->mf
.num_channels
= cfg
->num_channels
;
712 hw_cfg
->mf
.data_format
= module
->data_format
;
716 param_data
= &fs_cfg
->param_data
;
717 param_data
->module_instance_id
= module
->instance_id
;
718 param_data
->error_code
= 0;
719 param_data
->param_id
= PARAM_ID_HW_EP_FRAME_SIZE_FACTOR
;
720 param_data
->param_size
= fs_sz
- APM_MODULE_PARAM_DATA_SIZE
;
721 fs_cfg
->frame_size_factor
= 1;
725 param_data
= &intf_cfg
->param_data
;
726 param_data
->module_instance_id
= module
->instance_id
;
727 param_data
->error_code
= 0;
728 param_data
->param_id
= PARAM_ID_CODEC_DMA_INTF_CFG
;
729 param_data
->param_size
= ic_sz
- APM_MODULE_PARAM_DATA_SIZE
;
731 intf_cfg
->cfg
.lpaif_type
= module
->hw_interface_type
;
732 intf_cfg
->cfg
.intf_index
= module
->hw_interface_idx
;
733 intf_cfg
->cfg
.active_channels_mask
= (1 << cfg
->num_channels
) - 1;
737 param_data
= &pm_cfg
->param_data
;
738 param_data
->module_instance_id
= module
->instance_id
;
739 param_data
->error_code
= 0;
740 param_data
->param_id
= PARAM_ID_HW_EP_POWER_MODE_CFG
;
741 param_data
->param_size
= pm_sz
- APM_MODULE_PARAM_DATA_SIZE
;
742 pm_cfg
->power_mode
.power_mode
= 0;
744 rc
= q6apm_send_cmd_sync(graph
->apm
, pkt
, 0);
751 int audioreach_send_u32_param(struct q6apm_graph
*graph
, struct audioreach_module
*module
,
752 uint32_t param_id
, uint32_t param_val
)
754 struct apm_module_param_data
*param_data
;
757 int rc
, payload_size
;
760 payload_size
= sizeof(uint32_t) + APM_MODULE_PARAM_DATA_SIZE
;
761 p
= audioreach_alloc_apm_cmd_pkt(payload_size
, APM_CMD_SET_CFG
, 0);
766 p
= p
+ GPR_HDR_SIZE
+ APM_CMD_HDR_SIZE
;
769 param_data
->module_instance_id
= module
->instance_id
;
770 param_data
->error_code
= 0;
771 param_data
->param_id
= param_id
;
772 param_data
->param_size
= sizeof(uint32_t);
774 p
= p
+ APM_MODULE_PARAM_DATA_SIZE
;
778 rc
= q6apm_send_cmd_sync(graph
->apm
, pkt
, 0);
784 EXPORT_SYMBOL_GPL(audioreach_send_u32_param
);
786 static int audioreach_sal_limiter_enable(struct q6apm_graph
*graph
,
787 struct audioreach_module
*module
, bool enable
)
789 return audioreach_send_u32_param(graph
, module
, PARAM_ID_SAL_LIMITER_ENABLE
, enable
);
792 static int audioreach_sal_set_media_format(struct q6apm_graph
*graph
,
793 struct audioreach_module
*module
,
794 struct audioreach_module_config
*cfg
)
796 return audioreach_send_u32_param(graph
, module
, PARAM_ID_SAL_OUTPUT_CFG
, cfg
->bit_width
);
799 static int audioreach_module_enable(struct q6apm_graph
*graph
,
800 struct audioreach_module
*module
,
803 return audioreach_send_u32_param(graph
, module
, PARAM_ID_MODULE_ENABLE
, enable
);
806 static int audioreach_gapless_set_media_format(struct q6apm_graph
*graph
,
807 struct audioreach_module
*module
,
808 struct audioreach_module_config
*cfg
)
810 return audioreach_send_u32_param(graph
, module
, PARAM_ID_EARLY_EOS_DELAY
,
814 static int audioreach_mfc_set_media_format(struct q6apm_graph
*graph
,
815 struct audioreach_module
*module
,
816 struct audioreach_module_config
*cfg
)
818 struct apm_module_param_data
*param_data
;
819 struct param_id_mfc_media_format
*media_format
;
820 uint32_t num_channels
= cfg
->num_channels
;
826 payload_size
= APM_MFC_CFG_PSIZE(media_format
, num_channels
) +
827 APM_MODULE_PARAM_DATA_SIZE
;
829 pkt
= audioreach_alloc_apm_cmd_pkt(payload_size
, APM_CMD_SET_CFG
, 0);
833 p
= (void *)pkt
+ GPR_HDR_SIZE
+ APM_CMD_HDR_SIZE
;
836 param_data
->module_instance_id
= module
->instance_id
;
837 param_data
->error_code
= 0;
838 param_data
->param_id
= PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT
;
839 param_data
->param_size
= APM_MFC_CFG_PSIZE(media_format
, num_channels
);
840 p
= p
+ APM_MODULE_PARAM_DATA_SIZE
;
843 media_format
->sample_rate
= cfg
->sample_rate
;
844 media_format
->bit_width
= cfg
->bit_width
;
845 media_format
->num_channels
= cfg
->num_channels
;
846 for (i
= 0; i
< num_channels
; i
++)
847 media_format
->channel_mapping
[i
] = cfg
->channel_map
[i
];
849 rc
= q6apm_send_cmd_sync(graph
->apm
, pkt
, 0);
856 static int audioreach_set_compr_media_format(struct media_format
*media_fmt_hdr
,
857 void *p
, struct audioreach_module_config
*mcfg
)
859 struct payload_media_fmt_aac_t
*aac_cfg
;
860 struct payload_media_fmt_pcm
*mp3_cfg
;
861 struct payload_media_fmt_flac_t
*flac_cfg
;
864 case SND_AUDIOCODEC_MP3
:
865 media_fmt_hdr
->data_format
= DATA_FORMAT_RAW_COMPRESSED
;
866 media_fmt_hdr
->fmt_id
= MEDIA_FMT_ID_MP3
;
867 media_fmt_hdr
->payload_size
= 0;
868 p
= p
+ sizeof(*media_fmt_hdr
);
870 mp3_cfg
->sample_rate
= mcfg
->sample_rate
;
871 mp3_cfg
->bit_width
= mcfg
->bit_width
;
872 mp3_cfg
->alignment
= PCM_LSB_ALIGNED
;
873 mp3_cfg
->bits_per_sample
= mcfg
->bit_width
;
874 mp3_cfg
->q_factor
= mcfg
->bit_width
- 1;
875 mp3_cfg
->endianness
= PCM_LITTLE_ENDIAN
;
876 mp3_cfg
->num_channels
= mcfg
->num_channels
;
878 case SND_AUDIOCODEC_AAC
:
879 media_fmt_hdr
->data_format
= DATA_FORMAT_RAW_COMPRESSED
;
880 media_fmt_hdr
->fmt_id
= MEDIA_FMT_ID_AAC
;
881 media_fmt_hdr
->payload_size
= sizeof(struct payload_media_fmt_aac_t
);
882 p
= p
+ sizeof(*media_fmt_hdr
);
884 aac_cfg
->aac_fmt_flag
= 0;
885 aac_cfg
->audio_obj_type
= 5;
886 aac_cfg
->num_channels
= mcfg
->num_channels
;
887 aac_cfg
->total_size_of_PCE_bits
= 0;
888 aac_cfg
->sample_rate
= mcfg
->sample_rate
;
890 case SND_AUDIOCODEC_FLAC
:
891 media_fmt_hdr
->data_format
= DATA_FORMAT_RAW_COMPRESSED
;
892 media_fmt_hdr
->fmt_id
= MEDIA_FMT_ID_FLAC
;
893 media_fmt_hdr
->payload_size
= sizeof(struct payload_media_fmt_flac_t
);
894 p
= p
+ sizeof(*media_fmt_hdr
);
896 flac_cfg
->sample_size
= mcfg
->codec
.options
.flac_d
.sample_size
;
897 flac_cfg
->num_channels
= mcfg
->num_channels
;
898 flac_cfg
->min_blk_size
= mcfg
->codec
.options
.flac_d
.min_blk_size
;
899 flac_cfg
->max_blk_size
= mcfg
->codec
.options
.flac_d
.max_blk_size
;
900 flac_cfg
->sample_rate
= mcfg
->sample_rate
;
901 flac_cfg
->min_frame_size
= mcfg
->codec
.options
.flac_d
.min_frame_size
;
902 flac_cfg
->max_frame_size
= mcfg
->codec
.options
.flac_d
.max_frame_size
;
911 int audioreach_compr_set_param(struct q6apm_graph
*graph
, struct audioreach_module_config
*mcfg
)
913 struct media_format
*header
;
915 int iid
, payload_size
, rc
;
918 payload_size
= sizeof(struct apm_sh_module_media_fmt_cmd
);
920 iid
= q6apm_graph_get_rx_shmem_module_iid(graph
);
921 pkt
= audioreach_alloc_cmd_pkt(payload_size
, DATA_CMD_WR_SH_MEM_EP_MEDIA_FORMAT
,
922 0, graph
->port
->id
, iid
);
927 p
= (void *)pkt
+ GPR_HDR_SIZE
;
929 rc
= audioreach_set_compr_media_format(header
, p
, mcfg
);
935 rc
= gpr_send_port_pkt(graph
->port
, pkt
);
940 EXPORT_SYMBOL_GPL(audioreach_compr_set_param
);
942 static int audioreach_i2s_set_media_format(struct q6apm_graph
*graph
,
943 struct audioreach_module
*module
,
944 struct audioreach_module_config
*cfg
)
946 struct apm_module_frame_size_factor_cfg
*fs_cfg
;
947 struct apm_module_param_data
*param_data
;
948 struct apm_i2s_module_intf_cfg
*intf_cfg
;
949 struct apm_module_hw_ep_mf_cfg
*hw_cfg
;
950 int ic_sz
, ep_sz
, fs_sz
;
951 int rc
, payload_size
;
955 ic_sz
= APM_I2S_INTF_CFG_PSIZE
;
956 ep_sz
= APM_HW_EP_CFG_PSIZE
;
957 fs_sz
= APM_FS_CFG_PSIZE
;
959 payload_size
= ic_sz
+ ep_sz
+ fs_sz
;
961 pkt
= audioreach_alloc_apm_cmd_pkt(payload_size
, APM_CMD_SET_CFG
, 0);
965 p
= (void *)pkt
+ GPR_HDR_SIZE
+ APM_CMD_HDR_SIZE
;
968 param_data
= &intf_cfg
->param_data
;
969 param_data
->module_instance_id
= module
->instance_id
;
970 param_data
->error_code
= 0;
971 param_data
->param_id
= PARAM_ID_I2S_INTF_CFG
;
972 param_data
->param_size
= ic_sz
- APM_MODULE_PARAM_DATA_SIZE
;
974 intf_cfg
->cfg
.intf_idx
= module
->hw_interface_idx
;
975 intf_cfg
->cfg
.sd_line_idx
= module
->sd_line_idx
;
977 switch (cfg
->fmt
& SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK
) {
978 case SND_SOC_DAIFMT_BP_FP
:
979 intf_cfg
->cfg
.ws_src
= CONFIG_I2S_WS_SRC_INTERNAL
;
981 case SND_SOC_DAIFMT_BC_FC
:
983 intf_cfg
->cfg
.ws_src
= CONFIG_I2S_WS_SRC_EXTERNAL
;
991 param_data
= &hw_cfg
->param_data
;
992 param_data
->module_instance_id
= module
->instance_id
;
993 param_data
->error_code
= 0;
994 param_data
->param_id
= PARAM_ID_HW_EP_MF_CFG
;
995 param_data
->param_size
= ep_sz
- APM_MODULE_PARAM_DATA_SIZE
;
997 hw_cfg
->mf
.sample_rate
= cfg
->sample_rate
;
998 hw_cfg
->mf
.bit_width
= cfg
->bit_width
;
999 hw_cfg
->mf
.num_channels
= cfg
->num_channels
;
1000 hw_cfg
->mf
.data_format
= module
->data_format
;
1004 param_data
= &fs_cfg
->param_data
;
1005 param_data
->module_instance_id
= module
->instance_id
;
1006 param_data
->error_code
= 0;
1007 param_data
->param_id
= PARAM_ID_HW_EP_FRAME_SIZE_FACTOR
;
1008 param_data
->param_size
= fs_sz
- APM_MODULE_PARAM_DATA_SIZE
;
1009 fs_cfg
->frame_size_factor
= 1;
1011 rc
= q6apm_send_cmd_sync(graph
->apm
, pkt
, 0);
1018 static int audioreach_logging_set_media_format(struct q6apm_graph
*graph
,
1019 struct audioreach_module
*module
)
1021 struct apm_module_param_data
*param_data
;
1022 struct data_logging_config
*cfg
;
1023 int rc
, payload_size
;
1024 struct gpr_pkt
*pkt
;
1027 payload_size
= sizeof(*cfg
) + APM_MODULE_PARAM_DATA_SIZE
;
1028 pkt
= audioreach_alloc_apm_cmd_pkt(payload_size
, APM_CMD_SET_CFG
, 0);
1030 return PTR_ERR(pkt
);
1032 p
= (void *)pkt
+ GPR_HDR_SIZE
+ APM_CMD_HDR_SIZE
;
1035 param_data
->module_instance_id
= module
->instance_id
;
1036 param_data
->error_code
= 0;
1037 param_data
->param_id
= PARAM_ID_DATA_LOGGING_CONFIG
;
1038 param_data
->param_size
= payload_size
- APM_MODULE_PARAM_DATA_SIZE
;
1040 p
= p
+ APM_MODULE_PARAM_DATA_SIZE
;
1042 cfg
->log_code
= module
->log_code
;
1043 cfg
->log_tap_point_id
= module
->log_tap_point_id
;
1044 cfg
->mode
= module
->log_mode
;
1046 rc
= q6apm_send_cmd_sync(graph
->apm
, pkt
, 0);
1053 static int audioreach_pcm_set_media_format(struct q6apm_graph
*graph
,
1054 struct audioreach_module
*module
,
1055 struct audioreach_module_config
*mcfg
)
1057 struct payload_pcm_output_format_cfg
*media_cfg
;
1058 uint32_t num_channels
= mcfg
->num_channels
;
1059 struct apm_pcm_module_media_fmt_cmd
*cfg
;
1060 struct apm_module_param_data
*param_data
;
1061 int rc
, payload_size
;
1062 struct gpr_pkt
*pkt
;
1064 if (num_channels
> 4) {
1065 dev_err(graph
->dev
, "Error: Invalid channels (%d)!\n", num_channels
);
1069 payload_size
= APM_PCM_MODULE_FMT_CMD_PSIZE(num_channels
);
1071 pkt
= audioreach_alloc_apm_cmd_pkt(payload_size
, APM_CMD_SET_CFG
, 0);
1073 return PTR_ERR(pkt
);
1075 cfg
= (void *)pkt
+ GPR_HDR_SIZE
+ APM_CMD_HDR_SIZE
;
1077 param_data
= &cfg
->param_data
;
1078 param_data
->module_instance_id
= module
->instance_id
;
1079 param_data
->error_code
= 0;
1080 param_data
->param_id
= PARAM_ID_PCM_OUTPUT_FORMAT_CFG
;
1081 param_data
->param_size
= payload_size
- APM_MODULE_PARAM_DATA_SIZE
;
1083 cfg
->header
.data_format
= DATA_FORMAT_FIXED_POINT
;
1084 cfg
->header
.fmt_id
= MEDIA_FMT_ID_PCM
;
1085 cfg
->header
.payload_size
= APM_PCM_OUT_FMT_CFG_PSIZE(media_cfg
, num_channels
);
1087 media_cfg
= &cfg
->media_cfg
;
1088 media_cfg
->alignment
= PCM_LSB_ALIGNED
;
1089 media_cfg
->bit_width
= mcfg
->bit_width
;
1090 media_cfg
->endianness
= PCM_LITTLE_ENDIAN
;
1091 media_cfg
->interleaved
= module
->interleave_type
;
1092 media_cfg
->num_channels
= mcfg
->num_channels
;
1093 media_cfg
->q_factor
= mcfg
->bit_width
- 1;
1094 media_cfg
->bits_per_sample
= mcfg
->bit_width
;
1095 memcpy(media_cfg
->channel_mapping
, mcfg
->channel_map
, mcfg
->num_channels
);
1097 rc
= q6apm_send_cmd_sync(graph
->apm
, pkt
, 0);
1104 static int audioreach_shmem_set_media_format(struct q6apm_graph
*graph
,
1105 struct audioreach_module
*module
,
1106 struct audioreach_module_config
*mcfg
)
1108 uint32_t num_channels
= mcfg
->num_channels
;
1109 struct apm_module_param_data
*param_data
;
1110 struct payload_media_fmt_pcm
*cfg
;
1111 struct media_format
*header
;
1112 int rc
, payload_size
;
1113 struct gpr_pkt
*pkt
;
1116 if (num_channels
> 4) {
1117 dev_err(graph
->dev
, "Error: Invalid channels (%d)!\n", num_channels
);
1121 payload_size
= APM_SHMEM_FMT_CFG_PSIZE(num_channels
) + APM_MODULE_PARAM_DATA_SIZE
;
1123 pkt
= audioreach_alloc_cmd_pkt(payload_size
, APM_CMD_SET_CFG
, 0,
1124 graph
->port
->id
, module
->instance_id
);
1126 return PTR_ERR(pkt
);
1128 p
= (void *)pkt
+ GPR_HDR_SIZE
+ APM_CMD_HDR_SIZE
;
1131 param_data
->module_instance_id
= module
->instance_id
;
1132 param_data
->error_code
= 0;
1133 param_data
->param_id
= PARAM_ID_MEDIA_FORMAT
;
1134 param_data
->param_size
= payload_size
- APM_MODULE_PARAM_DATA_SIZE
;
1135 p
= p
+ APM_MODULE_PARAM_DATA_SIZE
;
1138 if (mcfg
->fmt
== SND_AUDIOCODEC_PCM
) {
1139 header
->data_format
= DATA_FORMAT_FIXED_POINT
;
1140 header
->fmt_id
= MEDIA_FMT_ID_PCM
;
1141 header
->payload_size
= payload_size
- sizeof(*header
);
1143 p
= p
+ sizeof(*header
);
1145 cfg
->sample_rate
= mcfg
->sample_rate
;
1146 cfg
->bit_width
= mcfg
->bit_width
;
1147 cfg
->alignment
= PCM_LSB_ALIGNED
;
1148 cfg
->bits_per_sample
= mcfg
->bit_width
;
1149 cfg
->q_factor
= mcfg
->bit_width
- 1;
1150 cfg
->endianness
= PCM_LITTLE_ENDIAN
;
1151 cfg
->num_channels
= mcfg
->num_channels
;
1152 memcpy(cfg
->channel_mapping
, mcfg
->channel_map
, mcfg
->num_channels
);
1154 rc
= audioreach_set_compr_media_format(header
, p
, mcfg
);
1161 rc
= audioreach_graph_send_cmd_sync(graph
, pkt
, 0);
1168 int audioreach_gain_set_vol_ctrl(struct q6apm
*apm
, struct audioreach_module
*module
, int vol
)
1170 struct param_id_vol_ctrl_master_gain
*cfg
;
1171 struct apm_module_param_data
*param_data
;
1172 int rc
, payload_size
;
1173 struct gpr_pkt
*pkt
;
1176 payload_size
= sizeof(*cfg
) + APM_MODULE_PARAM_DATA_SIZE
;
1177 pkt
= audioreach_alloc_apm_cmd_pkt(payload_size
, APM_CMD_SET_CFG
, 0);
1179 return PTR_ERR(pkt
);
1181 p
= (void *)pkt
+ GPR_HDR_SIZE
+ APM_CMD_HDR_SIZE
;
1184 param_data
->module_instance_id
= module
->instance_id
;
1185 param_data
->error_code
= 0;
1186 param_data
->param_id
= PARAM_ID_VOL_CTRL_MASTER_GAIN
;
1187 param_data
->param_size
= payload_size
- APM_MODULE_PARAM_DATA_SIZE
;
1189 p
= p
+ APM_MODULE_PARAM_DATA_SIZE
;
1191 cfg
->master_gain
= vol
;
1192 rc
= q6apm_send_cmd_sync(apm
, pkt
, 0);
1198 EXPORT_SYMBOL_GPL(audioreach_gain_set_vol_ctrl
);
1200 static int audioreach_gain_set(struct q6apm_graph
*graph
, struct audioreach_module
*module
)
1202 struct apm_module_param_data
*param_data
;
1203 struct apm_gain_module_cfg
*cfg
;
1204 int rc
, payload_size
;
1205 struct gpr_pkt
*pkt
;
1207 payload_size
= APM_GAIN_CFG_PSIZE
;
1208 pkt
= audioreach_alloc_apm_cmd_pkt(payload_size
, APM_CMD_SET_CFG
, 0);
1210 return PTR_ERR(pkt
);
1212 cfg
= (void *)pkt
+ GPR_HDR_SIZE
+ APM_CMD_HDR_SIZE
;
1214 param_data
= &cfg
->param_data
;
1215 param_data
->module_instance_id
= module
->instance_id
;
1216 param_data
->error_code
= 0;
1217 param_data
->param_id
= APM_PARAM_ID_GAIN
;
1218 param_data
->param_size
= payload_size
- APM_MODULE_PARAM_DATA_SIZE
;
1220 cfg
->gain_cfg
.gain
= module
->gain
;
1222 rc
= q6apm_send_cmd_sync(graph
->apm
, pkt
, 0);
1229 int audioreach_set_media_format(struct q6apm_graph
*graph
, struct audioreach_module
*module
,
1230 struct audioreach_module_config
*cfg
)
1234 switch (module
->module_id
) {
1235 case MODULE_ID_DATA_LOGGING
:
1236 rc
= audioreach_module_enable(graph
, module
, true);
1238 rc
= audioreach_logging_set_media_format(graph
, module
);
1240 case MODULE_ID_PCM_DEC
:
1241 case MODULE_ID_PCM_ENC
:
1242 case MODULE_ID_PCM_CNV
:
1243 case MODULE_ID_PLACEHOLDER_DECODER
:
1244 case MODULE_ID_PLACEHOLDER_ENCODER
:
1245 rc
= audioreach_pcm_set_media_format(graph
, module
, cfg
);
1247 case MODULE_ID_DISPLAY_PORT_SINK
:
1248 rc
= audioreach_display_port_set_media_format(graph
, module
, cfg
);
1250 case MODULE_ID_I2S_SOURCE
:
1251 case MODULE_ID_I2S_SINK
:
1252 rc
= audioreach_i2s_set_media_format(graph
, module
, cfg
);
1254 case MODULE_ID_WR_SHARED_MEM_EP
:
1255 rc
= audioreach_shmem_set_media_format(graph
, module
, cfg
);
1257 case MODULE_ID_GAIN
:
1258 rc
= audioreach_gain_set(graph
, module
);
1260 case MODULE_ID_CODEC_DMA_SINK
:
1261 case MODULE_ID_CODEC_DMA_SOURCE
:
1262 rc
= audioreach_codec_dma_set_media_format(graph
, module
, cfg
);
1265 rc
= audioreach_sal_set_media_format(graph
, module
, cfg
);
1267 rc
= audioreach_sal_limiter_enable(graph
, module
, true);
1270 rc
= audioreach_mfc_set_media_format(graph
, module
, cfg
);
1272 case MODULE_ID_GAPLESS
:
1273 rc
= audioreach_gapless_set_media_format(graph
, module
, cfg
);
1281 EXPORT_SYMBOL_GPL(audioreach_set_media_format
);
1283 void audioreach_graph_free_buf(struct q6apm_graph
*graph
)
1285 struct audioreach_graph_data
*port
;
1287 mutex_lock(&graph
->lock
);
1288 port
= &graph
->rx_data
;
1289 port
->num_periods
= 0;
1293 port
= &graph
->tx_data
;
1294 port
->num_periods
= 0;
1297 mutex_unlock(&graph
->lock
);
1299 EXPORT_SYMBOL_GPL(audioreach_graph_free_buf
);
1301 int audioreach_map_memory_regions(struct q6apm_graph
*graph
, unsigned int dir
, size_t period_sz
,
1302 unsigned int periods
, bool is_contiguous
)
1304 struct apm_shared_map_region_payload
*mregions
;
1305 struct apm_cmd_shared_mem_map_regions
*cmd
;
1306 uint32_t num_regions
, buf_sz
, payload_size
;
1307 struct audioreach_graph_data
*data
;
1308 struct gpr_pkt
*pkt
;
1312 if (dir
== SNDRV_PCM_STREAM_PLAYBACK
)
1313 data
= &graph
->rx_data
;
1315 data
= &graph
->tx_data
;
1317 if (is_contiguous
) {
1319 buf_sz
= period_sz
* periods
;
1322 num_regions
= periods
;
1325 /* DSP expects size should be aligned to 4K */
1326 buf_sz
= ALIGN(buf_sz
, 4096);
1328 payload_size
= sizeof(*cmd
) + (sizeof(*mregions
) * num_regions
);
1330 pkt
= audioreach_alloc_apm_pkt(payload_size
, APM_CMD_SHARED_MEM_MAP_REGIONS
, dir
,
1333 return PTR_ERR(pkt
);
1335 p
= (void *)pkt
+ GPR_HDR_SIZE
;
1337 cmd
->mem_pool_id
= APM_MEMORY_MAP_SHMEM8_4K_POOL
;
1338 cmd
->num_regions
= num_regions
;
1340 cmd
->property_flag
= 0x0;
1342 mregions
= p
+ sizeof(*cmd
);
1344 mutex_lock(&graph
->lock
);
1346 for (i
= 0; i
< num_regions
; i
++) {
1347 struct audio_buffer
*ab
;
1350 mregions
->shm_addr_lsw
= lower_32_bits(ab
->phys
);
1351 mregions
->shm_addr_msw
= upper_32_bits(ab
->phys
);
1352 mregions
->mem_size_bytes
= buf_sz
;
1355 mutex_unlock(&graph
->lock
);
1357 rc
= audioreach_graph_send_cmd_sync(graph
, pkt
, APM_CMD_RSP_SHARED_MEM_MAP_REGIONS
);
1363 EXPORT_SYMBOL_GPL(audioreach_map_memory_regions
);
1365 int audioreach_shared_memory_send_eos(struct q6apm_graph
*graph
)
1367 struct data_cmd_wr_sh_mem_ep_eos
*eos
;
1368 struct gpr_pkt
*pkt
;
1371 iid
= q6apm_graph_get_rx_shmem_module_iid(graph
);
1372 pkt
= audioreach_alloc_cmd_pkt(sizeof(*eos
), DATA_CMD_WR_SH_MEM_EP_EOS
, 0,
1373 graph
->port
->id
, iid
);
1375 return PTR_ERR(pkt
);
1377 eos
= (void *)pkt
+ GPR_HDR_SIZE
+ APM_CMD_HDR_SIZE
;
1379 eos
->policy
= WR_SH_MEM_EP_EOS_POLICY_LAST
;
1381 rc
= gpr_send_port_pkt(graph
->port
, pkt
);
1386 EXPORT_SYMBOL_GPL(audioreach_shared_memory_send_eos
);