1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2020, Linaro Limited
4 #include <linux/cleanup.h>
6 #include <sound/soc-dapm.h>
8 #include <sound/control.h>
9 #include <sound/asound.h>
10 #include <linux/firmware.h>
11 #include <sound/soc-topology.h>
12 #include <sound/soc-dpcm.h>
13 #include <uapi/sound/snd_ar_tokens.h>
14 #include <linux/kernel.h>
15 #include <linux/wait.h>
17 #include "audioreach.h"
19 struct snd_ar_control
{
20 u32 graph_id
; /* Graph ID */
21 u32 sgid
; /* Sub Graph ID */
22 u32 module_instance_id
; /* Connected Module Instance ID */
23 struct snd_soc_dapm_widget
*w
;
24 struct list_head node
;
25 struct snd_soc_component
*scomp
;
28 static struct audioreach_graph_info
*audioreach_tplg_alloc_graph_info(struct q6apm
*apm
,
32 struct audioreach_graph_info
*info
;
35 mutex_lock(&apm
->lock
);
36 info
= idr_find(&apm
->graph_info_idr
, graph_id
);
37 mutex_unlock(&apm
->lock
);
45 info
= kzalloc(sizeof(*info
), GFP_KERNEL
);
47 return ERR_PTR(-ENOMEM
);
49 INIT_LIST_HEAD(&info
->sg_list
);
51 mutex_lock(&apm
->lock
);
52 ret
= idr_alloc_u32(&apm
->graph_info_idr
, info
, &graph_id
, graph_id
, GFP_KERNEL
);
53 mutex_unlock(&apm
->lock
);
56 dev_err(apm
->dev
, "Failed to allocate Graph ID (%x)\n", graph_id
);
66 static void audioreach_tplg_add_sub_graph(struct audioreach_sub_graph
*sg
,
67 struct audioreach_graph_info
*info
)
69 list_add_tail(&sg
->node
, &info
->sg_list
);
71 info
->num_sub_graphs
++;
74 static struct audioreach_sub_graph
*audioreach_tplg_alloc_sub_graph(struct q6apm
*apm
,
75 uint32_t sub_graph_id
,
78 struct audioreach_sub_graph
*sg
;
82 return ERR_PTR(-EINVAL
);
84 /* Find if there is already a matching sub-graph */
85 mutex_lock(&apm
->lock
);
86 sg
= idr_find(&apm
->sub_graphs_idr
, sub_graph_id
);
87 mutex_unlock(&apm
->lock
);
95 sg
= kzalloc(sizeof(*sg
), GFP_KERNEL
);
97 return ERR_PTR(-ENOMEM
);
99 INIT_LIST_HEAD(&sg
->container_list
);
101 mutex_lock(&apm
->lock
);
102 ret
= idr_alloc_u32(&apm
->sub_graphs_idr
, sg
, &sub_graph_id
, sub_graph_id
, GFP_KERNEL
);
103 mutex_unlock(&apm
->lock
);
106 dev_err(apm
->dev
, "Failed to allocate Sub-Graph Instance ID (%x)\n", sub_graph_id
);
111 sg
->sub_graph_id
= sub_graph_id
;
116 static struct audioreach_container
*audioreach_tplg_alloc_container(struct q6apm
*apm
,
117 struct audioreach_sub_graph
*sg
,
118 uint32_t container_id
,
121 struct audioreach_container
*cont
;
125 return ERR_PTR(-EINVAL
);
127 mutex_lock(&apm
->lock
);
128 cont
= idr_find(&apm
->containers_idr
, container_id
);
129 mutex_unlock(&apm
->lock
);
137 cont
= kzalloc(sizeof(*cont
), GFP_KERNEL
);
139 return ERR_PTR(-ENOMEM
);
141 INIT_LIST_HEAD(&cont
->modules_list
);
143 mutex_lock(&apm
->lock
);
144 ret
= idr_alloc_u32(&apm
->containers_idr
, cont
, &container_id
, container_id
, GFP_KERNEL
);
145 mutex_unlock(&apm
->lock
);
148 dev_err(apm
->dev
, "Failed to allocate Container Instance ID (%x)\n", container_id
);
153 cont
->container_id
= container_id
;
154 cont
->sub_graph
= sg
;
155 /* add to container list */
156 list_add_tail(&cont
->node
, &sg
->container_list
);
157 sg
->num_containers
++;
162 static struct audioreach_module
*audioreach_tplg_alloc_module(struct q6apm
*apm
,
163 struct audioreach_container
*cont
,
164 struct snd_soc_dapm_widget
*w
,
165 uint32_t module_id
, bool *found
)
167 struct audioreach_module
*mod
;
170 mutex_lock(&apm
->lock
);
171 mod
= idr_find(&apm
->modules_idr
, module_id
);
172 mutex_unlock(&apm
->lock
);
179 mod
= kzalloc(sizeof(*mod
), GFP_KERNEL
);
181 return ERR_PTR(-ENOMEM
);
183 mutex_lock(&apm
->lock
);
184 if (!module_id
) { /* alloc module id dynamically */
185 ret
= idr_alloc_cyclic(&apm
->modules_idr
, mod
,
186 AR_MODULE_DYNAMIC_INSTANCE_ID_START
,
187 AR_MODULE_DYNAMIC_INSTANCE_ID_END
, GFP_KERNEL
);
189 ret
= idr_alloc_u32(&apm
->modules_idr
, mod
, &module_id
, module_id
, GFP_KERNEL
);
191 mutex_unlock(&apm
->lock
);
194 dev_err(apm
->dev
, "Failed to allocate Module Instance ID (%x)\n", module_id
);
199 mod
->instance_id
= module_id
;
200 /* add to module list */
201 list_add_tail(&mod
->node
, &cont
->modules_list
);
202 mod
->container
= cont
;
209 static struct snd_soc_tplg_vendor_array
*audioreach_get_sg_array(
210 struct snd_soc_tplg_private
*private)
212 struct snd_soc_tplg_vendor_array
*sg_array
= NULL
;
216 for (sz
= 0; !found
&& (sz
< le32_to_cpu(private->size
)); ) {
217 struct snd_soc_tplg_vendor_value_elem
*sg_elem
;
220 sg_array
= (struct snd_soc_tplg_vendor_array
*)((u8
*)private->array
+ sz
);
221 sg_elem
= sg_array
->value
;
222 sz
= sz
+ le32_to_cpu(sg_array
->size
);
223 while (!found
&& tkn_count
<= (le32_to_cpu(sg_array
->num_elems
) - 1)) {
224 switch (le32_to_cpu(sg_elem
->token
)) {
225 case AR_TKN_U32_SUB_GRAPH_INSTANCE_ID
:
242 static struct snd_soc_tplg_vendor_array
*audioreach_get_cont_array(
243 struct snd_soc_tplg_private
*private)
245 struct snd_soc_tplg_vendor_array
*cont_array
= NULL
;
249 for (sz
= 0; !found
&& (sz
< le32_to_cpu(private->size
)); ) {
250 struct snd_soc_tplg_vendor_value_elem
*cont_elem
;
253 cont_array
= (struct snd_soc_tplg_vendor_array
*)((u8
*)private->array
+ sz
);
254 cont_elem
= cont_array
->value
;
255 sz
= sz
+ le32_to_cpu(cont_array
->size
);
256 while (!found
&& tkn_count
<= (le32_to_cpu(cont_array
->num_elems
) - 1)) {
257 switch (le32_to_cpu(cont_elem
->token
)) {
258 case AR_TKN_U32_CONTAINER_INSTANCE_ID
:
275 static struct snd_soc_tplg_vendor_array
*audioreach_get_module_array(
276 struct snd_soc_tplg_private
*private)
278 struct snd_soc_tplg_vendor_array
*mod_array
= NULL
;
282 for (sz
= 0; !found
&& (sz
< le32_to_cpu(private->size
)); ) {
283 struct snd_soc_tplg_vendor_value_elem
*mod_elem
;
286 mod_array
= (struct snd_soc_tplg_vendor_array
*)((u8
*)private->array
+ sz
);
287 mod_elem
= mod_array
->value
;
288 sz
= sz
+ le32_to_cpu(mod_array
->size
);
289 while (!found
&& tkn_count
<= (le32_to_cpu(mod_array
->num_elems
) - 1)) {
290 switch (le32_to_cpu(mod_elem
->token
)) {
291 case AR_TKN_U32_MODULE_INSTANCE_ID
:
308 static struct audioreach_sub_graph
*audioreach_parse_sg_tokens(struct q6apm
*apm
,
309 struct snd_soc_tplg_private
*private)
311 struct snd_soc_tplg_vendor_value_elem
*sg_elem
;
312 struct snd_soc_tplg_vendor_array
*sg_array
;
313 struct audioreach_graph_info
*info
= NULL
;
314 int graph_id
, sub_graph_id
, tkn_count
= 0;
315 struct audioreach_sub_graph
*sg
;
318 sg_array
= audioreach_get_sg_array(private);
319 sg_elem
= sg_array
->value
;
321 while (tkn_count
<= (le32_to_cpu(sg_array
->num_elems
) - 1)) {
322 switch (le32_to_cpu(sg_elem
->token
)) {
323 case AR_TKN_U32_SUB_GRAPH_INSTANCE_ID
:
324 sub_graph_id
= le32_to_cpu(sg_elem
->value
);
325 sg
= audioreach_tplg_alloc_sub_graph(apm
, sub_graph_id
, &found
);
329 /* Already parsed data for this sub-graph */
333 case AR_TKN_DAI_INDEX
:
334 /* Sub graph is associated with predefined graph */
335 graph_id
= le32_to_cpu(sg_elem
->value
);
336 info
= audioreach_tplg_alloc_graph_info(apm
, graph_id
, &found
);
338 return ERR_CAST(info
);
340 case AR_TKN_U32_SUB_GRAPH_PERF_MODE
:
341 sg
->perf_mode
= le32_to_cpu(sg_elem
->value
);
343 case AR_TKN_U32_SUB_GRAPH_DIRECTION
:
344 sg
->direction
= le32_to_cpu(sg_elem
->value
);
346 case AR_TKN_U32_SUB_GRAPH_SCENARIO_ID
:
347 sg
->scenario_id
= le32_to_cpu(sg_elem
->value
);
350 dev_err(apm
->dev
, "Not a valid token %d for graph\n", sg_elem
->token
);
358 /* Sub graph is associated with predefined graph */
360 audioreach_tplg_add_sub_graph(sg
, info
);
365 static struct audioreach_container
*audioreach_parse_cont_tokens(struct q6apm
*apm
,
366 struct audioreach_sub_graph
*sg
,
367 struct snd_soc_tplg_private
*private)
369 struct snd_soc_tplg_vendor_value_elem
*cont_elem
;
370 struct snd_soc_tplg_vendor_array
*cont_array
;
371 struct audioreach_container
*cont
;
372 int container_id
, tkn_count
= 0;
375 cont_array
= audioreach_get_cont_array(private);
376 cont_elem
= cont_array
->value
;
378 while (tkn_count
<= (le32_to_cpu(cont_array
->num_elems
) - 1)) {
379 switch (le32_to_cpu(cont_elem
->token
)) {
380 case AR_TKN_U32_CONTAINER_INSTANCE_ID
:
381 container_id
= le32_to_cpu(cont_elem
->value
);
382 cont
= audioreach_tplg_alloc_container(apm
, sg
, container_id
, &found
);
383 if (IS_ERR(cont
) || found
)/* Error or Already parsed container data */
386 case AR_TKN_U32_CONTAINER_CAPABILITY_ID
:
387 cont
->capability_id
= le32_to_cpu(cont_elem
->value
);
389 case AR_TKN_U32_CONTAINER_STACK_SIZE
:
390 cont
->stack_size
= le32_to_cpu(cont_elem
->value
);
392 case AR_TKN_U32_CONTAINER_GRAPH_POS
:
393 cont
->graph_pos
= le32_to_cpu(cont_elem
->value
);
395 case AR_TKN_U32_CONTAINER_PROC_DOMAIN
:
396 cont
->proc_domain
= le32_to_cpu(cont_elem
->value
);
399 dev_err(apm
->dev
, "Not a valid token %d for graph\n", cont_elem
->token
);
410 static struct audioreach_module
*audioreach_parse_common_tokens(struct q6apm
*apm
,
411 struct audioreach_container
*cont
,
412 struct snd_soc_tplg_private
*private,
413 struct snd_soc_dapm_widget
*w
)
415 uint32_t max_ip_port
= 0, max_op_port
= 0, in_port
= 0, out_port
= 0;
416 uint32_t src_mod_op_port_id
[AR_MAX_MOD_LINKS
] = { 0, };
417 uint32_t dst_mod_inst_id
[AR_MAX_MOD_LINKS
] = { 0, };
418 uint32_t dst_mod_ip_port_id
[AR_MAX_MOD_LINKS
] = { 0, };
419 uint32_t src_mod_inst_id
= 0;
421 int module_id
= 0, instance_id
= 0, tkn_count
= 0;
422 struct snd_soc_tplg_vendor_value_elem
*mod_elem
;
423 struct snd_soc_tplg_vendor_array
*mod_array
;
424 struct audioreach_module
*mod
= NULL
;
429 mod_array
= audioreach_get_module_array(private);
430 mod_elem
= mod_array
->value
;
431 max_tokens
= le32_to_cpu(mod_array
->num_elems
);
432 while (tkn_count
<= (max_tokens
- 1)) {
433 token
= le32_to_cpu(mod_elem
->token
);
435 /* common module info */
436 case AR_TKN_U32_MODULE_ID
:
437 module_id
= le32_to_cpu(mod_elem
->value
);
439 case AR_TKN_U32_MODULE_INSTANCE_ID
:
440 instance_id
= le32_to_cpu(mod_elem
->value
);
441 mod
= audioreach_tplg_alloc_module(apm
, cont
, w
,
442 instance_id
, &found
);
446 dev_err(apm
->dev
, "Duplicate Module Instance ID 0x%08x found\n",
448 return ERR_PTR(-EINVAL
);
452 case AR_TKN_U32_MODULE_MAX_IP_PORTS
:
453 max_ip_port
= le32_to_cpu(mod_elem
->value
);
455 case AR_TKN_U32_MODULE_MAX_OP_PORTS
:
456 max_op_port
= le32_to_cpu(mod_elem
->value
);
458 case AR_TKN_U32_MODULE_IN_PORTS
:
459 in_port
= le32_to_cpu(mod_elem
->value
);
461 case AR_TKN_U32_MODULE_OUT_PORTS
:
462 out_port
= le32_to_cpu(mod_elem
->value
);
464 case AR_TKN_U32_MODULE_SRC_INSTANCE_ID
:
465 src_mod_inst_id
= le32_to_cpu(mod_elem
->value
);
467 case AR_TKN_U32_MODULE_SRC_OP_PORT_ID
:
468 src_mod_op_port_id
[0] = le32_to_cpu(mod_elem
->value
);
470 case AR_TKN_U32_MODULE_SRC_OP_PORT_ID1
:
471 src_mod_op_port_id
[1] = le32_to_cpu(mod_elem
->value
);
473 case AR_TKN_U32_MODULE_SRC_OP_PORT_ID2
:
474 src_mod_op_port_id
[2] = le32_to_cpu(mod_elem
->value
);
476 case AR_TKN_U32_MODULE_SRC_OP_PORT_ID3
:
477 src_mod_op_port_id
[3] = le32_to_cpu(mod_elem
->value
);
479 case AR_TKN_U32_MODULE_SRC_OP_PORT_ID4
:
480 src_mod_op_port_id
[4] = le32_to_cpu(mod_elem
->value
);
482 case AR_TKN_U32_MODULE_SRC_OP_PORT_ID5
:
483 src_mod_op_port_id
[5] = le32_to_cpu(mod_elem
->value
);
485 case AR_TKN_U32_MODULE_SRC_OP_PORT_ID6
:
486 src_mod_op_port_id
[6] = le32_to_cpu(mod_elem
->value
);
488 case AR_TKN_U32_MODULE_SRC_OP_PORT_ID7
:
489 src_mod_op_port_id
[7] = le32_to_cpu(mod_elem
->value
);
491 case AR_TKN_U32_MODULE_DST_INSTANCE_ID
:
492 dst_mod_inst_id
[0] = le32_to_cpu(mod_elem
->value
);
494 case AR_TKN_U32_MODULE_DST_INSTANCE_ID1
:
495 dst_mod_inst_id
[1] = le32_to_cpu(mod_elem
->value
);
497 case AR_TKN_U32_MODULE_DST_INSTANCE_ID2
:
498 dst_mod_inst_id
[2] = le32_to_cpu(mod_elem
->value
);
500 case AR_TKN_U32_MODULE_DST_INSTANCE_ID3
:
501 dst_mod_inst_id
[3] = le32_to_cpu(mod_elem
->value
);
503 case AR_TKN_U32_MODULE_DST_INSTANCE_ID4
:
504 dst_mod_inst_id
[4] = le32_to_cpu(mod_elem
->value
);
506 case AR_TKN_U32_MODULE_DST_INSTANCE_ID5
:
507 dst_mod_inst_id
[5] = le32_to_cpu(mod_elem
->value
);
509 case AR_TKN_U32_MODULE_DST_INSTANCE_ID6
:
510 dst_mod_inst_id
[6] = le32_to_cpu(mod_elem
->value
);
512 case AR_TKN_U32_MODULE_DST_INSTANCE_ID7
:
513 dst_mod_inst_id
[7] = le32_to_cpu(mod_elem
->value
);
515 case AR_TKN_U32_MODULE_DST_IN_PORT_ID
:
516 dst_mod_ip_port_id
[0] = le32_to_cpu(mod_elem
->value
);
518 case AR_TKN_U32_MODULE_DST_IN_PORT_ID1
:
519 dst_mod_ip_port_id
[1] = le32_to_cpu(mod_elem
->value
);
521 case AR_TKN_U32_MODULE_DST_IN_PORT_ID2
:
522 dst_mod_ip_port_id
[2] = le32_to_cpu(mod_elem
->value
);
524 case AR_TKN_U32_MODULE_DST_IN_PORT_ID3
:
525 dst_mod_ip_port_id
[3] = le32_to_cpu(mod_elem
->value
);
527 case AR_TKN_U32_MODULE_DST_IN_PORT_ID4
:
528 dst_mod_ip_port_id
[4] = le32_to_cpu(mod_elem
->value
);
530 case AR_TKN_U32_MODULE_DST_IN_PORT_ID5
:
531 dst_mod_ip_port_id
[5] = le32_to_cpu(mod_elem
->value
);
533 case AR_TKN_U32_MODULE_DST_IN_PORT_ID6
:
534 dst_mod_ip_port_id
[6] = le32_to_cpu(mod_elem
->value
);
536 case AR_TKN_U32_MODULE_DST_IN_PORT_ID7
:
537 dst_mod_ip_port_id
[7] = le32_to_cpu(mod_elem
->value
);
550 mod
->module_id
= module_id
;
551 mod
->max_ip_port
= max_ip_port
;
552 mod
->max_op_port
= max_op_port
;
553 mod
->in_port
= in_port
;
554 mod
->out_port
= out_port
;
555 mod
->src_mod_inst_id
= src_mod_inst_id
;
556 for (pn
= 0; pn
< mod
->max_op_port
; pn
++) {
557 if (src_mod_op_port_id
[pn
] && dst_mod_inst_id
[pn
] &&
558 dst_mod_ip_port_id
[pn
]) {
559 mod
->src_mod_op_port_id
[id
] = src_mod_op_port_id
[pn
];
560 mod
->dst_mod_inst_id
[id
] = dst_mod_inst_id
[pn
];
561 mod
->dst_mod_ip_port_id
[id
] = dst_mod_ip_port_id
[pn
];
563 mod
->num_connections
= id
;
571 static int audioreach_widget_load_module_common(struct snd_soc_component
*component
,
572 int index
, struct snd_soc_dapm_widget
*w
,
573 struct snd_soc_tplg_dapm_widget
*tplg_w
)
575 struct q6apm
*apm
= dev_get_drvdata(component
->dev
);
576 struct audioreach_container
*cont
;
577 struct audioreach_sub_graph
*sg
;
578 struct audioreach_module
*mod
;
579 struct snd_soc_dobj
*dobj
;
581 sg
= audioreach_parse_sg_tokens(apm
, &tplg_w
->priv
);
585 cont
= audioreach_parse_cont_tokens(apm
, sg
, &tplg_w
->priv
);
587 return PTR_ERR(cont
);
589 mod
= audioreach_parse_common_tokens(apm
, cont
, &tplg_w
->priv
, w
);
599 static int audioreach_widget_load_enc_dec_cnv(struct snd_soc_component
*component
,
600 int index
, struct snd_soc_dapm_widget
*w
,
601 struct snd_soc_tplg_dapm_widget
*tplg_w
)
603 struct snd_soc_tplg_vendor_value_elem
*mod_elem
;
604 struct snd_soc_tplg_vendor_array
*mod_array
;
605 struct audioreach_module
*mod
;
606 struct snd_soc_dobj
*dobj
;
610 ret
= audioreach_widget_load_module_common(component
, index
, w
, tplg_w
);
616 mod_array
= audioreach_get_module_array(&tplg_w
->priv
);
617 mod_elem
= mod_array
->value
;
619 while (tkn_count
<= (le32_to_cpu(mod_array
->num_elems
) - 1)) {
620 switch (le32_to_cpu(mod_elem
->token
)) {
621 case AR_TKN_U32_MODULE_FMT_INTERLEAVE
:
622 mod
->interleave_type
= le32_to_cpu(mod_elem
->value
);
624 case AR_TKN_U32_MODULE_FMT_SAMPLE_RATE
:
625 mod
->rate
= le32_to_cpu(mod_elem
->value
);
627 case AR_TKN_U32_MODULE_FMT_BIT_DEPTH
:
628 mod
->bit_depth
= le32_to_cpu(mod_elem
->value
);
640 static int audioreach_widget_log_module_load(struct audioreach_module
*mod
,
641 struct snd_soc_tplg_vendor_array
*mod_array
)
643 struct snd_soc_tplg_vendor_value_elem
*mod_elem
;
646 mod_elem
= mod_array
->value
;
648 while (tkn_count
<= (le32_to_cpu(mod_array
->num_elems
) - 1)) {
649 switch (le32_to_cpu(mod_elem
->token
)) {
651 case AR_TKN_U32_MODULE_LOG_CODE
:
652 mod
->log_code
= le32_to_cpu(mod_elem
->value
);
654 case AR_TKN_U32_MODULE_LOG_TAP_POINT_ID
:
655 mod
->log_tap_point_id
= le32_to_cpu(mod_elem
->value
);
657 case AR_TKN_U32_MODULE_LOG_MODE
:
658 mod
->log_mode
= le32_to_cpu(mod_elem
->value
);
670 static int audioreach_widget_dma_module_load(struct audioreach_module
*mod
,
671 struct snd_soc_tplg_vendor_array
*mod_array
)
673 struct snd_soc_tplg_vendor_value_elem
*mod_elem
;
676 mod_elem
= mod_array
->value
;
678 while (tkn_count
<= (le32_to_cpu(mod_array
->num_elems
) - 1)) {
679 switch (le32_to_cpu(mod_elem
->token
)) {
680 case AR_TKN_U32_MODULE_HW_IF_IDX
:
681 mod
->hw_interface_idx
= le32_to_cpu(mod_elem
->value
);
683 case AR_TKN_U32_MODULE_FMT_DATA
:
684 mod
->data_format
= le32_to_cpu(mod_elem
->value
);
686 case AR_TKN_U32_MODULE_HW_IF_TYPE
:
687 mod
->hw_interface_type
= le32_to_cpu(mod_elem
->value
);
699 static int audioreach_widget_i2s_module_load(struct audioreach_module
*mod
,
700 struct snd_soc_tplg_vendor_array
*mod_array
)
702 struct snd_soc_tplg_vendor_value_elem
*mod_elem
;
705 mod_elem
= mod_array
->value
;
707 while (tkn_count
<= (le32_to_cpu(mod_array
->num_elems
) - 1)) {
708 switch (le32_to_cpu(mod_elem
->token
)) {
709 case AR_TKN_U32_MODULE_HW_IF_IDX
:
710 mod
->hw_interface_idx
= le32_to_cpu(mod_elem
->value
);
712 case AR_TKN_U32_MODULE_FMT_DATA
:
713 mod
->data_format
= le32_to_cpu(mod_elem
->value
);
715 case AR_TKN_U32_MODULE_HW_IF_TYPE
:
716 mod
->hw_interface_type
= le32_to_cpu(mod_elem
->value
);
718 case AR_TKN_U32_MODULE_SD_LINE_IDX
:
719 mod
->sd_line_idx
= le32_to_cpu(mod_elem
->value
);
721 case AR_TKN_U32_MODULE_WS_SRC
:
722 mod
->ws_src
= le32_to_cpu(mod_elem
->value
);
734 static int audioreach_widget_dp_module_load(struct audioreach_module
*mod
,
735 struct snd_soc_tplg_vendor_array
*mod_array
)
737 struct snd_soc_tplg_vendor_value_elem
*mod_elem
;
740 mod_elem
= mod_array
->value
;
742 while (tkn_count
<= (le32_to_cpu(mod_array
->num_elems
) - 1)) {
743 switch (le32_to_cpu(mod_elem
->token
)) {
744 case AR_TKN_U32_MODULE_FMT_DATA
:
745 mod
->data_format
= le32_to_cpu(mod_elem
->value
);
757 static int audioreach_widget_load_buffer(struct snd_soc_component
*component
,
758 int index
, struct snd_soc_dapm_widget
*w
,
759 struct snd_soc_tplg_dapm_widget
*tplg_w
)
761 struct snd_soc_tplg_vendor_array
*mod_array
;
762 struct audioreach_module
*mod
;
763 struct snd_soc_dobj
*dobj
;
766 ret
= audioreach_widget_load_module_common(component
, index
, w
, tplg_w
);
773 mod_array
= audioreach_get_module_array(&tplg_w
->priv
);
775 switch (mod
->module_id
) {
776 case MODULE_ID_CODEC_DMA_SINK
:
777 case MODULE_ID_CODEC_DMA_SOURCE
:
778 audioreach_widget_dma_module_load(mod
, mod_array
);
780 case MODULE_ID_DATA_LOGGING
:
781 audioreach_widget_log_module_load(mod
, mod_array
);
783 case MODULE_ID_I2S_SINK
:
784 case MODULE_ID_I2S_SOURCE
:
785 audioreach_widget_i2s_module_load(mod
, mod_array
);
787 case MODULE_ID_DISPLAY_PORT_SINK
:
788 audioreach_widget_dp_module_load(mod
, mod_array
);
797 static int audioreach_widget_load_mixer(struct snd_soc_component
*component
,
798 int index
, struct snd_soc_dapm_widget
*w
,
799 struct snd_soc_tplg_dapm_widget
*tplg_w
)
801 struct snd_soc_tplg_vendor_value_elem
*w_elem
;
802 struct snd_soc_tplg_vendor_array
*w_array
;
803 struct snd_ar_control
*scontrol
;
804 struct q6apm
*data
= dev_get_drvdata(component
->dev
);
805 struct snd_soc_dobj
*dobj
;
808 w_array
= &tplg_w
->priv
.array
[0];
810 scontrol
= kzalloc(sizeof(*scontrol
), GFP_KERNEL
);
814 scontrol
->scomp
= component
;
816 dobj
->private = scontrol
;
818 w_elem
= w_array
->value
;
819 while (tkn_count
<= (le32_to_cpu(w_array
->num_elems
) - 1)) {
820 switch (le32_to_cpu(w_elem
->token
)) {
821 case AR_TKN_U32_SUB_GRAPH_INSTANCE_ID
:
822 scontrol
->sgid
= le32_to_cpu(w_elem
->value
);
824 case AR_TKN_DAI_INDEX
:
825 scontrol
->graph_id
= le32_to_cpu(w_elem
->value
);
827 default: /* ignore other tokens */
835 list_add_tail(&scontrol
->node
, &data
->widget_list
);
840 static int audioreach_pga_event(struct snd_soc_dapm_widget
*w
,
841 struct snd_kcontrol
*kcontrol
, int event
)
844 struct snd_soc_dapm_context
*dapm
= w
->dapm
;
845 struct snd_soc_component
*c
= snd_soc_dapm_to_component(dapm
);
846 struct audioreach_module
*mod
= w
->dobj
.private;
847 struct q6apm
*apm
= dev_get_drvdata(c
->dev
);
850 case SND_SOC_DAPM_POST_PMU
:
851 /* apply gain after power up of widget */
852 audioreach_gain_set_vol_ctrl(apm
, mod
, mod
->gain
);
861 static const struct snd_soc_tplg_widget_events audioreach_widget_ops
[] = {
862 { AR_PGA_DAPM_EVENT
, audioreach_pga_event
},
865 static int audioreach_widget_load_pga(struct snd_soc_component
*component
,
866 int index
, struct snd_soc_dapm_widget
*w
,
867 struct snd_soc_tplg_dapm_widget
*tplg_w
)
869 struct audioreach_module
*mod
;
870 struct snd_soc_dobj
*dobj
;
873 ret
= audioreach_widget_load_module_common(component
, index
, w
, tplg_w
);
879 mod
->gain
= VOL_CTRL_DEFAULT_GAIN
;
881 ret
= snd_soc_tplg_widget_bind_event(w
, audioreach_widget_ops
,
882 ARRAY_SIZE(audioreach_widget_ops
),
883 le16_to_cpu(tplg_w
->event_type
));
885 dev_err(component
->dev
, "matching event handlers NOT found for %d\n",
886 le16_to_cpu(tplg_w
->event_type
));
893 static int audioreach_widget_ready(struct snd_soc_component
*component
,
894 int index
, struct snd_soc_dapm_widget
*w
,
895 struct snd_soc_tplg_dapm_widget
*tplg_w
)
898 case snd_soc_dapm_aif_in
:
899 case snd_soc_dapm_aif_out
:
900 audioreach_widget_load_buffer(component
, index
, w
, tplg_w
);
902 case snd_soc_dapm_decoder
:
903 case snd_soc_dapm_encoder
:
904 case snd_soc_dapm_src
:
905 audioreach_widget_load_enc_dec_cnv(component
, index
, w
, tplg_w
);
907 case snd_soc_dapm_buffer
:
908 audioreach_widget_load_buffer(component
, index
, w
, tplg_w
);
910 case snd_soc_dapm_mixer
:
911 return audioreach_widget_load_mixer(component
, index
, w
, tplg_w
);
912 case snd_soc_dapm_pga
:
913 return audioreach_widget_load_pga(component
, index
, w
, tplg_w
);
914 case snd_soc_dapm_dai_link
:
915 case snd_soc_dapm_scheduler
:
916 case snd_soc_dapm_out_drv
:
918 dev_err(component
->dev
, "Widget type (0x%x) not yet supported\n", w
->id
);
925 static int audioreach_widget_unload(struct snd_soc_component
*scomp
,
926 struct snd_soc_dobj
*dobj
)
928 struct snd_soc_dapm_widget
*w
= container_of(dobj
, struct snd_soc_dapm_widget
, dobj
);
929 struct q6apm
*apm
= dev_get_drvdata(scomp
->dev
);
930 struct audioreach_container
*cont
;
931 struct audioreach_module
*mod
;
934 cont
= mod
->container
;
936 if (w
->id
== snd_soc_dapm_mixer
) {
938 struct snd_ar_control
*scontrol
= dobj
->private;
940 list_del(&scontrol
->node
);
945 mutex_lock(&apm
->lock
);
946 idr_remove(&apm
->modules_idr
, mod
->instance_id
);
949 list_del(&mod
->node
);
951 /* Graph Info has N sub-graphs, sub-graph has N containers, Container has N Modules */
952 if (list_empty(&cont
->modules_list
)) { /* if no modules in the container then remove it */
953 struct audioreach_sub_graph
*sg
= cont
->sub_graph
;
955 idr_remove(&apm
->containers_idr
, cont
->container_id
);
956 list_del(&cont
->node
);
957 sg
->num_containers
--;
959 /* check if there are no more containers in the sub graph and remove it */
960 if (list_empty(&sg
->container_list
)) {
961 struct audioreach_graph_info
*info
= sg
->info
;
963 idr_remove(&apm
->sub_graphs_idr
, sg
->sub_graph_id
);
965 info
->num_sub_graphs
--;
967 /* Check if there are no more sub-graphs left then remove graph info */
968 if (list_empty(&info
->sg_list
)) {
969 idr_remove(&apm
->graph_info_idr
, info
->id
);
975 mutex_unlock(&apm
->lock
);
980 static struct snd_ar_control
*audioreach_find_widget(struct snd_soc_component
*comp
,
983 struct q6apm
*apm
= dev_get_drvdata(comp
->dev
);
984 struct snd_ar_control
*control
;
986 list_for_each_entry(control
, &apm
->widget_list
, node
) {
987 if (control
->w
&& !strcmp(name
, control
->w
->name
))
994 static struct audioreach_module
*audioreach_find_module(struct snd_soc_component
*comp
,
997 struct q6apm
*apm
= dev_get_drvdata(comp
->dev
);
998 struct audioreach_module
*module
;
1001 idr_for_each_entry(&apm
->modules_idr
, module
, id
) {
1002 if (!strcmp(name
, module
->widget
->name
))
1009 static int audioreach_route_load(struct snd_soc_component
*scomp
, int index
,
1010 struct snd_soc_dapm_route
*route
)
1012 struct audioreach_module
*src_module
, *sink_module
;
1013 struct snd_ar_control
*control
;
1014 struct snd_soc_dapm_widget
*w
;
1017 /* check if these are actual modules */
1018 src_module
= audioreach_find_module(scomp
, route
->source
);
1019 sink_module
= audioreach_find_module(scomp
, route
->sink
);
1021 if (sink_module
&& !src_module
) {
1022 control
= audioreach_find_widget(scomp
, route
->source
);
1024 control
->module_instance_id
= sink_module
->instance_id
;
1026 } else if (!sink_module
&& src_module
&& route
->control
) {
1027 /* check if this is a virtual mixer */
1028 control
= audioreach_find_widget(scomp
, route
->sink
);
1029 if (!control
|| !control
->w
)
1034 for (i
= 0; i
< w
->num_kcontrols
; i
++) {
1035 if (!strcmp(route
->control
, w
->kcontrol_news
[i
].name
)) {
1036 struct soc_mixer_control
*sm
;
1037 struct snd_soc_dobj
*dobj
;
1038 struct snd_ar_control
*scontrol
;
1040 sm
= (struct soc_mixer_control
*)w
->kcontrol_news
[i
].private_value
;
1042 scontrol
= dobj
->private;
1043 scontrol
->module_instance_id
= src_module
->instance_id
;
1052 static int audioreach_route_unload(struct snd_soc_component
*scomp
,
1053 struct snd_soc_dobj
*dobj
)
1058 static int audioreach_tplg_complete(struct snd_soc_component
*component
)
1064 /* DAI link - used for any driver specific init */
1065 static int audioreach_link_load(struct snd_soc_component
*component
, int index
,
1066 struct snd_soc_dai_link
*link
,
1067 struct snd_soc_tplg_link_config
*cfg
)
1069 link
->nonatomic
= true;
1070 link
->dynamic
= true;
1071 link
->platforms
->name
= NULL
;
1072 link
->platforms
->of_node
= of_get_compatible_child(component
->dev
->of_node
,
1077 static void audioreach_connect_sub_graphs(struct q6apm
*apm
,
1078 struct snd_ar_control
*m1
,
1079 struct snd_ar_control
*m2
,
1082 struct audioreach_graph_info
*info
;
1084 mutex_lock(&apm
->lock
);
1085 info
= idr_find(&apm
->graph_info_idr
, m2
->graph_id
);
1086 mutex_unlock(&apm
->lock
);
1089 info
->src_mod_inst_id
= m1
->module_instance_id
;
1090 info
->src_mod_op_port_id
= 1;
1091 info
->dst_mod_inst_id
= m2
->module_instance_id
;
1092 info
->dst_mod_ip_port_id
= 2;
1095 info
->src_mod_inst_id
= 0;
1096 info
->src_mod_op_port_id
= 0;
1097 info
->dst_mod_inst_id
= 0;
1098 info
->dst_mod_ip_port_id
= 0;
1102 static bool audioreach_is_vmixer_connected(struct q6apm
*apm
,
1103 struct snd_ar_control
*m1
,
1104 struct snd_ar_control
*m2
)
1106 struct audioreach_graph_info
*info
;
1108 mutex_lock(&apm
->lock
);
1109 info
= idr_find(&apm
->graph_info_idr
, m2
->graph_id
);
1110 mutex_unlock(&apm
->lock
);
1112 if (info
->dst_mod_inst_id
== m2
->module_instance_id
&&
1113 info
->src_mod_inst_id
== m1
->module_instance_id
)
1119 static int audioreach_get_audio_mixer(struct snd_kcontrol
*kcontrol
,
1120 struct snd_ctl_elem_value
*ucontrol
)
1122 struct soc_mixer_control
*mc
= (struct soc_mixer_control
*)kcontrol
->private_value
;
1123 struct snd_soc_dapm_context
*dapm
= snd_soc_dapm_kcontrol_dapm(kcontrol
);
1124 struct snd_soc_dapm_widget
*dw
= snd_soc_dapm_kcontrol_widget(kcontrol
);
1125 struct snd_soc_component
*c
= snd_soc_dapm_to_component(dapm
);
1126 struct snd_ar_control
*dapm_scontrol
= dw
->dobj
.private;
1127 struct snd_ar_control
*scontrol
= mc
->dobj
.private;
1128 struct q6apm
*data
= dev_get_drvdata(c
->dev
);
1131 connected
= audioreach_is_vmixer_connected(data
, scontrol
, dapm_scontrol
);
1133 ucontrol
->value
.integer
.value
[0] = 1;
1135 ucontrol
->value
.integer
.value
[0] = 0;
1140 static int audioreach_put_audio_mixer(struct snd_kcontrol
*kcontrol
,
1141 struct snd_ctl_elem_value
*ucontrol
)
1143 struct soc_mixer_control
*mc
= (struct soc_mixer_control
*)kcontrol
->private_value
;
1144 struct snd_soc_dapm_context
*dapm
= snd_soc_dapm_kcontrol_dapm(kcontrol
);
1145 struct snd_soc_dapm_widget
*dw
= snd_soc_dapm_kcontrol_widget(kcontrol
);
1146 struct snd_soc_component
*c
= snd_soc_dapm_to_component(dapm
);
1147 struct snd_ar_control
*dapm_scontrol
= dw
->dobj
.private;
1148 struct snd_ar_control
*scontrol
= mc
->dobj
.private;
1149 struct q6apm
*data
= dev_get_drvdata(c
->dev
);
1151 if (ucontrol
->value
.integer
.value
[0]) {
1152 audioreach_connect_sub_graphs(data
, scontrol
, dapm_scontrol
, true);
1153 snd_soc_dapm_mixer_update_power(dapm
, kcontrol
, 1, NULL
);
1155 audioreach_connect_sub_graphs(data
, scontrol
, dapm_scontrol
, false);
1156 snd_soc_dapm_mixer_update_power(dapm
, kcontrol
, 0, NULL
);
1161 static int audioreach_get_vol_ctrl_audio_mixer(struct snd_kcontrol
*kcontrol
,
1162 struct snd_ctl_elem_value
*ucontrol
)
1164 struct snd_soc_dapm_widget
*dw
= snd_soc_dapm_kcontrol_widget(kcontrol
);
1165 struct audioreach_module
*mod
= dw
->dobj
.private;
1167 ucontrol
->value
.integer
.value
[0] = mod
->gain
;
1172 static int audioreach_put_vol_ctrl_audio_mixer(struct snd_kcontrol
*kcontrol
,
1173 struct snd_ctl_elem_value
*ucontrol
)
1175 struct snd_soc_dapm_widget
*dw
= snd_soc_dapm_kcontrol_widget(kcontrol
);
1176 struct audioreach_module
*mod
= dw
->dobj
.private;
1178 mod
->gain
= ucontrol
->value
.integer
.value
[0];
1183 static int audioreach_control_load_mix(struct snd_soc_component
*scomp
,
1184 struct snd_ar_control
*scontrol
,
1185 struct snd_kcontrol_new
*kc
,
1186 struct snd_soc_tplg_ctl_hdr
*hdr
)
1188 struct snd_soc_tplg_vendor_value_elem
*c_elem
;
1189 struct snd_soc_tplg_vendor_array
*c_array
;
1190 struct snd_soc_tplg_mixer_control
*mc
;
1193 mc
= container_of(hdr
, struct snd_soc_tplg_mixer_control
, hdr
);
1194 c_array
= (struct snd_soc_tplg_vendor_array
*)mc
->priv
.data
;
1196 c_elem
= c_array
->value
;
1198 while (tkn_count
<= (le32_to_cpu(c_array
->num_elems
) - 1)) {
1199 switch (le32_to_cpu(c_elem
->token
)) {
1200 case AR_TKN_U32_SUB_GRAPH_INSTANCE_ID
:
1201 scontrol
->sgid
= le32_to_cpu(c_elem
->value
);
1203 case AR_TKN_DAI_INDEX
:
1204 scontrol
->graph_id
= le32_to_cpu(c_elem
->value
);
1207 /* Ignore other tokens */
1217 static int audioreach_control_load(struct snd_soc_component
*scomp
, int index
,
1218 struct snd_kcontrol_new
*kc
,
1219 struct snd_soc_tplg_ctl_hdr
*hdr
)
1221 struct snd_ar_control
*scontrol
;
1222 struct soc_mixer_control
*sm
;
1223 struct snd_soc_dobj
*dobj
;
1226 scontrol
= kzalloc(sizeof(*scontrol
), GFP_KERNEL
);
1230 scontrol
->scomp
= scomp
;
1232 switch (le32_to_cpu(hdr
->ops
.get
)) {
1233 case SND_SOC_AR_TPLG_FE_BE_GRAPH_CTL_MIX
:
1234 sm
= (struct soc_mixer_control
*)kc
->private_value
;
1236 ret
= audioreach_control_load_mix(scomp
, scontrol
, kc
, hdr
);
1238 case SND_SOC_AR_TPLG_VOL_CTL
:
1239 sm
= (struct soc_mixer_control
*)kc
->private_value
;
1243 dev_warn(scomp
->dev
, "control type not supported %d:%d:%d\n",
1244 hdr
->ops
.get
, hdr
->ops
.put
, hdr
->ops
.info
);
1249 dobj
->private = scontrol
;
1253 static int audioreach_control_unload(struct snd_soc_component
*scomp
,
1254 struct snd_soc_dobj
*dobj
)
1256 struct snd_ar_control
*scontrol
= dobj
->private;
1263 static const struct snd_soc_tplg_kcontrol_ops audioreach_io_ops
[] = {
1264 {SND_SOC_AR_TPLG_FE_BE_GRAPH_CTL_MIX
, audioreach_get_audio_mixer
,
1265 audioreach_put_audio_mixer
, snd_soc_info_volsw
},
1266 {SND_SOC_AR_TPLG_VOL_CTL
, audioreach_get_vol_ctrl_audio_mixer
,
1267 audioreach_put_vol_ctrl_audio_mixer
, snd_soc_info_volsw
},
1270 static const struct snd_soc_tplg_ops audioreach_tplg_ops
= {
1271 .io_ops
= audioreach_io_ops
,
1272 .io_ops_count
= ARRAY_SIZE(audioreach_io_ops
),
1274 .control_load
= audioreach_control_load
,
1275 .control_unload
= audioreach_control_unload
,
1277 .widget_ready
= audioreach_widget_ready
,
1278 .widget_unload
= audioreach_widget_unload
,
1280 .complete
= audioreach_tplg_complete
,
1281 .link_load
= audioreach_link_load
,
1283 .dapm_route_load
= audioreach_route_load
,
1284 .dapm_route_unload
= audioreach_route_unload
,
1287 int audioreach_tplg_init(struct snd_soc_component
*component
)
1289 struct snd_soc_card
*card
= component
->card
;
1290 struct device
*dev
= component
->dev
;
1291 const struct firmware
*fw
;
1294 /* Inline with Qualcomm UCM configs and linux-firmware path */
1295 char *tplg_fw_name
__free(kfree
) = kasprintf(GFP_KERNEL
, "qcom/%s/%s-tplg.bin",
1301 ret
= request_firmware(&fw
, tplg_fw_name
, dev
);
1303 dev_err(dev
, "tplg firmware loading %s failed %d\n", tplg_fw_name
, ret
);
1307 ret
= snd_soc_tplg_component_load(component
, &audioreach_tplg_ops
, fw
);
1309 if (ret
!= -EPROBE_DEFER
)
1310 dev_err(dev
, "tplg component load failed: %d\n", ret
);
1313 release_firmware(fw
);
1317 EXPORT_SYMBOL_GPL(audioreach_tplg_init
);