arm64: dts: qcom: sm8550: add TRNG node
[linux-modified.git] / sound / soc / qcom / qdsp6 / topology.c
1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2020, Linaro Limited
3
4 #include <sound/soc.h>
5 #include <sound/soc-dapm.h>
6 #include <sound/pcm.h>
7 #include <sound/control.h>
8 #include <sound/asound.h>
9 #include <linux/firmware.h>
10 #include <sound/soc-topology.h>
11 #include <sound/soc-dpcm.h>
12 #include <uapi/sound/snd_ar_tokens.h>
13 #include <linux/kernel.h>
14 #include <linux/wait.h>
15 #include "q6apm.h"
16 #include "audioreach.h"
17
18 struct snd_ar_control {
19         u32 graph_id; /* Graph ID */
20         u32 sgid; /* Sub Graph ID */
21         u32 module_instance_id; /* Connected Module Instance ID */
22         struct snd_soc_dapm_widget *w;
23         struct list_head node;
24         struct snd_soc_component *scomp;
25 };
26
27 static struct audioreach_graph_info *audioreach_tplg_alloc_graph_info(struct q6apm *apm,
28                                                                       uint32_t graph_id,
29                                                                       bool *found)
30 {
31         struct audioreach_graph_info *info;
32         int ret;
33
34         mutex_lock(&apm->lock);
35         info = idr_find(&apm->graph_info_idr, graph_id);
36         mutex_unlock(&apm->lock);
37
38         if (info) {
39                 *found = true;
40                 return info;
41         }
42
43         *found = false;
44         info = kzalloc(sizeof(*info), GFP_KERNEL);
45         if (!info)
46                 return ERR_PTR(-ENOMEM);
47
48         INIT_LIST_HEAD(&info->sg_list);
49
50         mutex_lock(&apm->lock);
51         ret = idr_alloc_u32(&apm->graph_info_idr, info, &graph_id, graph_id, GFP_KERNEL);
52         mutex_unlock(&apm->lock);
53
54         if (ret < 0) {
55                 dev_err(apm->dev, "Failed to allocate Graph ID (%x)\n", graph_id);
56                 kfree(info);
57                 return ERR_PTR(ret);
58         }
59
60         info->id = graph_id;
61
62         return info;
63 }
64
65 static void audioreach_tplg_add_sub_graph(struct audioreach_sub_graph *sg,
66                                           struct audioreach_graph_info *info)
67 {
68         list_add_tail(&sg->node, &info->sg_list);
69         sg->info = info;
70         info->num_sub_graphs++;
71 }
72
73 static struct audioreach_sub_graph *audioreach_tplg_alloc_sub_graph(struct q6apm *apm,
74                                                                     uint32_t sub_graph_id,
75                                                                     bool *found)
76 {
77         struct audioreach_sub_graph *sg;
78         int ret;
79
80         if (!sub_graph_id)
81                 return ERR_PTR(-EINVAL);
82
83         /* Find if there is already a matching sub-graph */
84         mutex_lock(&apm->lock);
85         sg = idr_find(&apm->sub_graphs_idr, sub_graph_id);
86         mutex_unlock(&apm->lock);
87
88         if (sg) {
89                 *found = true;
90                 return sg;
91         }
92
93         *found = false;
94         sg = kzalloc(sizeof(*sg), GFP_KERNEL);
95         if (!sg)
96                 return ERR_PTR(-ENOMEM);
97
98         INIT_LIST_HEAD(&sg->container_list);
99
100         mutex_lock(&apm->lock);
101         ret = idr_alloc_u32(&apm->sub_graphs_idr, sg, &sub_graph_id, sub_graph_id, GFP_KERNEL);
102         mutex_unlock(&apm->lock);
103
104         if (ret < 0) {
105                 dev_err(apm->dev, "Failed to allocate Sub-Graph Instance ID (%x)\n", sub_graph_id);
106                 kfree(sg);
107                 return ERR_PTR(ret);
108         }
109
110         sg->sub_graph_id = sub_graph_id;
111
112         return sg;
113 }
114
115 static struct audioreach_container *audioreach_tplg_alloc_container(struct q6apm *apm,
116                                                             struct audioreach_sub_graph *sg,
117                                                             uint32_t container_id,
118                                                             bool *found)
119 {
120         struct audioreach_container *cont;
121         int ret;
122
123         if (!container_id)
124                 return ERR_PTR(-EINVAL);
125
126         mutex_lock(&apm->lock);
127         cont = idr_find(&apm->containers_idr, container_id);
128         mutex_unlock(&apm->lock);
129
130         if (cont) {
131                 *found = true;
132                 return cont;
133         }
134         *found = false;
135
136         cont = kzalloc(sizeof(*cont), GFP_KERNEL);
137         if (!cont)
138                 return ERR_PTR(-ENOMEM);
139
140         INIT_LIST_HEAD(&cont->modules_list);
141
142         mutex_lock(&apm->lock);
143         ret = idr_alloc_u32(&apm->containers_idr, cont, &container_id, container_id, GFP_KERNEL);
144         mutex_unlock(&apm->lock);
145
146         if (ret < 0) {
147                 dev_err(apm->dev, "Failed to allocate Container Instance ID (%x)\n", container_id);
148                 kfree(cont);
149                 return ERR_PTR(ret);
150         }
151
152         cont->container_id = container_id;
153         cont->sub_graph = sg;
154         /* add to container list */
155         list_add_tail(&cont->node, &sg->container_list);
156         sg->num_containers++;
157
158         return cont;
159 }
160
161 static struct audioreach_module *audioreach_tplg_alloc_module(struct q6apm *apm,
162                                                               struct audioreach_container *cont,
163                                                               struct snd_soc_dapm_widget *w,
164                                                               uint32_t module_id, bool *found)
165 {
166         struct audioreach_module *mod;
167         int ret;
168
169         mutex_lock(&apm->lock);
170         mod = idr_find(&apm->modules_idr, module_id);
171         mutex_unlock(&apm->lock);
172
173         if (mod) {
174                 *found = true;
175                 return mod;
176         }
177         *found = false;
178         mod = kzalloc(sizeof(*mod), GFP_KERNEL);
179         if (!mod)
180                 return ERR_PTR(-ENOMEM);
181
182         mutex_lock(&apm->lock);
183         if (!module_id) { /* alloc module id dynamically */
184                 ret = idr_alloc_cyclic(&apm->modules_idr, mod,
185                                        AR_MODULE_DYNAMIC_INSTANCE_ID_START,
186                                        AR_MODULE_DYNAMIC_INSTANCE_ID_END, GFP_KERNEL);
187         } else {
188                 ret = idr_alloc_u32(&apm->modules_idr, mod, &module_id, module_id, GFP_KERNEL);
189         }
190         mutex_unlock(&apm->lock);
191
192         if (ret < 0) {
193                 dev_err(apm->dev, "Failed to allocate Module Instance ID (%x)\n", module_id);
194                 kfree(mod);
195                 return ERR_PTR(ret);
196         }
197
198         mod->instance_id = module_id;
199         /* add to module list */
200         list_add_tail(&mod->node, &cont->modules_list);
201         mod->container = cont;
202         mod->widget = w;
203         cont->num_modules++;
204
205         return mod;
206 }
207
208 static struct snd_soc_tplg_vendor_array *audioreach_get_sg_array(
209                                                         struct snd_soc_tplg_private *private)
210 {
211         struct snd_soc_tplg_vendor_array *sg_array = NULL;
212         bool found = false;
213         int sz;
214
215         for (sz = 0; !found && (sz < le32_to_cpu(private->size)); ) {
216                 struct snd_soc_tplg_vendor_value_elem *sg_elem;
217                 int tkn_count = 0;
218
219                 sg_array = (struct snd_soc_tplg_vendor_array *)((u8 *)private->array + sz);
220                 sg_elem = sg_array->value;
221                 sz = sz + le32_to_cpu(sg_array->size);
222                 while (!found && tkn_count <= (le32_to_cpu(sg_array->num_elems) - 1)) {
223                         switch (le32_to_cpu(sg_elem->token)) {
224                         case AR_TKN_U32_SUB_GRAPH_INSTANCE_ID:
225                                 found = true;
226                                 break;
227                         default:
228                                 break;
229                         }
230                         tkn_count++;
231                         sg_elem++;
232                 }
233         }
234
235         if (found)
236                 return sg_array;
237
238         return NULL;
239 }
240
241 static struct snd_soc_tplg_vendor_array *audioreach_get_cont_array(
242                                                         struct snd_soc_tplg_private *private)
243 {
244         struct snd_soc_tplg_vendor_array *cont_array = NULL;
245         bool found = false;
246         int sz;
247
248         for (sz = 0; !found && (sz < le32_to_cpu(private->size)); ) {
249                 struct snd_soc_tplg_vendor_value_elem *cont_elem;
250                 int tkn_count = 0;
251
252                 cont_array = (struct snd_soc_tplg_vendor_array *)((u8 *)private->array + sz);
253                 cont_elem = cont_array->value;
254                 sz = sz + le32_to_cpu(cont_array->size);
255                 while (!found && tkn_count <= (le32_to_cpu(cont_array->num_elems) - 1)) {
256                         switch (le32_to_cpu(cont_elem->token)) {
257                         case AR_TKN_U32_CONTAINER_INSTANCE_ID:
258                                 found = true;
259                                 break;
260                         default:
261                                 break;
262                         }
263                         tkn_count++;
264                         cont_elem++;
265                 }
266         }
267
268         if (found)
269                 return cont_array;
270
271         return NULL;
272 }
273
274 static struct snd_soc_tplg_vendor_array *audioreach_get_module_array(
275                                                              struct snd_soc_tplg_private *private)
276 {
277         struct snd_soc_tplg_vendor_array *mod_array = NULL;
278         bool found = false;
279         int sz = 0;
280
281         for (sz = 0; !found && (sz < le32_to_cpu(private->size)); ) {
282                 struct snd_soc_tplg_vendor_value_elem *mod_elem;
283                 int tkn_count = 0;
284
285                 mod_array = (struct snd_soc_tplg_vendor_array *)((u8 *)private->array + sz);
286                 mod_elem = mod_array->value;
287                 sz = sz + le32_to_cpu(mod_array->size);
288                 while (!found && tkn_count <= (le32_to_cpu(mod_array->num_elems) - 1)) {
289                         switch (le32_to_cpu(mod_elem->token)) {
290                         case AR_TKN_U32_MODULE_INSTANCE_ID:
291                                 found = true;
292                                 break;
293                         default:
294                                 break;
295                         }
296                         tkn_count++;
297                         mod_elem++;
298                 }
299         }
300
301         if (found)
302                 return mod_array;
303
304         return NULL;
305 }
306
307 static struct audioreach_sub_graph *audioreach_parse_sg_tokens(struct q6apm *apm,
308                                                        struct snd_soc_tplg_private *private)
309 {
310         struct snd_soc_tplg_vendor_value_elem *sg_elem;
311         struct snd_soc_tplg_vendor_array *sg_array;
312         struct audioreach_graph_info *info = NULL;
313         int graph_id, sub_graph_id, tkn_count = 0;
314         struct audioreach_sub_graph *sg;
315         bool found;
316
317         sg_array = audioreach_get_sg_array(private);
318         sg_elem = sg_array->value;
319
320         while (tkn_count <= (le32_to_cpu(sg_array->num_elems) - 1)) {
321                 switch (le32_to_cpu(sg_elem->token)) {
322                 case AR_TKN_U32_SUB_GRAPH_INSTANCE_ID:
323                         sub_graph_id = le32_to_cpu(sg_elem->value);
324                         sg = audioreach_tplg_alloc_sub_graph(apm, sub_graph_id, &found);
325                         if (IS_ERR(sg)) {
326                                 return sg;
327                         } else if (found) {
328                                 /* Already parsed data for this sub-graph */
329                                 return sg;
330                         }
331                         break;
332                 case AR_TKN_DAI_INDEX:
333                         /* Sub graph is associated with predefined graph */
334                         graph_id = le32_to_cpu(sg_elem->value);
335                         info = audioreach_tplg_alloc_graph_info(apm, graph_id, &found);
336                         if (IS_ERR(info))
337                                 return ERR_CAST(info);
338                         break;
339                 case AR_TKN_U32_SUB_GRAPH_PERF_MODE:
340                         sg->perf_mode = le32_to_cpu(sg_elem->value);
341                         break;
342                 case AR_TKN_U32_SUB_GRAPH_DIRECTION:
343                         sg->direction = le32_to_cpu(sg_elem->value);
344                         break;
345                 case AR_TKN_U32_SUB_GRAPH_SCENARIO_ID:
346                         sg->scenario_id = le32_to_cpu(sg_elem->value);
347                         break;
348                 default:
349                         dev_err(apm->dev, "Not a valid token %d for graph\n", sg_elem->token);
350                         break;
351
352                 }
353                 tkn_count++;
354                 sg_elem++;
355         }
356
357         /* Sub graph is associated with predefined graph */
358         if (info)
359                 audioreach_tplg_add_sub_graph(sg, info);
360
361         return sg;
362 }
363
364 static struct audioreach_container *audioreach_parse_cont_tokens(struct q6apm *apm,
365                                                          struct audioreach_sub_graph *sg,
366                                                          struct snd_soc_tplg_private *private)
367 {
368         struct snd_soc_tplg_vendor_value_elem *cont_elem;
369         struct snd_soc_tplg_vendor_array *cont_array;
370         struct audioreach_container *cont;
371         int container_id, tkn_count = 0;
372         bool found = false;
373
374         cont_array = audioreach_get_cont_array(private);
375         cont_elem = cont_array->value;
376
377         while (tkn_count <= (le32_to_cpu(cont_array->num_elems) - 1)) {
378                 switch (le32_to_cpu(cont_elem->token)) {
379                 case AR_TKN_U32_CONTAINER_INSTANCE_ID:
380                         container_id = le32_to_cpu(cont_elem->value);
381                         cont = audioreach_tplg_alloc_container(apm, sg, container_id, &found);
382                         if (IS_ERR(cont) || found)/* Error or Already parsed container data */
383                                 return cont;
384                         break;
385                 case AR_TKN_U32_CONTAINER_CAPABILITY_ID:
386                         cont->capability_id = le32_to_cpu(cont_elem->value);
387                         break;
388                 case AR_TKN_U32_CONTAINER_STACK_SIZE:
389                         cont->stack_size = le32_to_cpu(cont_elem->value);
390                         break;
391                 case AR_TKN_U32_CONTAINER_GRAPH_POS:
392                         cont->graph_pos = le32_to_cpu(cont_elem->value);
393                         break;
394                 case AR_TKN_U32_CONTAINER_PROC_DOMAIN:
395                         cont->proc_domain = le32_to_cpu(cont_elem->value);
396                         break;
397                 default:
398                         dev_err(apm->dev, "Not a valid token %d for graph\n", cont_elem->token);
399                         break;
400
401                 }
402                 tkn_count++;
403                 cont_elem++;
404         }
405
406         return cont;
407 }
408
409 static struct audioreach_module *audioreach_parse_common_tokens(struct q6apm *apm,
410                                                         struct audioreach_container *cont,
411                                                         struct snd_soc_tplg_private *private,
412                                                         struct snd_soc_dapm_widget *w)
413 {
414         uint32_t max_ip_port = 0, max_op_port = 0, in_port = 0, out_port = 0;
415         uint32_t src_mod_op_port_id[AR_MAX_MOD_LINKS] = { 0, };
416         uint32_t dst_mod_inst_id[AR_MAX_MOD_LINKS] = { 0, };
417         uint32_t dst_mod_ip_port_id[AR_MAX_MOD_LINKS] = { 0, };
418         uint32_t src_mod_inst_id = 0;
419
420         int module_id = 0, instance_id = 0, tkn_count = 0;
421         struct snd_soc_tplg_vendor_value_elem *mod_elem;
422         struct snd_soc_tplg_vendor_array *mod_array;
423         struct audioreach_module *mod = NULL;
424         uint32_t token;
425         bool found;
426         int max_tokens;
427
428         mod_array = audioreach_get_module_array(private);
429         mod_elem = mod_array->value;
430         max_tokens = le32_to_cpu(mod_array->num_elems);
431         while (tkn_count <= (max_tokens - 1)) {
432                 token = le32_to_cpu(mod_elem->token);
433                 switch (token) {
434                 /* common module info */
435                 case AR_TKN_U32_MODULE_ID:
436                         module_id = le32_to_cpu(mod_elem->value);
437                         break;
438                 case AR_TKN_U32_MODULE_INSTANCE_ID:
439                         instance_id = le32_to_cpu(mod_elem->value);
440                         mod = audioreach_tplg_alloc_module(apm, cont, w,
441                                                            instance_id, &found);
442                         if (IS_ERR(mod)) {
443                                 return mod;
444                         } else if (found) {
445                                 dev_err(apm->dev, "Duplicate Module Instance ID 0x%08x found\n",
446                                         instance_id);
447                                 return ERR_PTR(-EINVAL);
448                         }
449
450                         break;
451                 case AR_TKN_U32_MODULE_MAX_IP_PORTS:
452                         max_ip_port = le32_to_cpu(mod_elem->value);
453                         break;
454                 case AR_TKN_U32_MODULE_MAX_OP_PORTS:
455                         max_op_port = le32_to_cpu(mod_elem->value);
456                         break;
457                 case AR_TKN_U32_MODULE_IN_PORTS:
458                         in_port = le32_to_cpu(mod_elem->value);
459                         break;
460                 case AR_TKN_U32_MODULE_OUT_PORTS:
461                         out_port = le32_to_cpu(mod_elem->value);
462                         break;
463                 case AR_TKN_U32_MODULE_SRC_INSTANCE_ID:
464                         src_mod_inst_id = le32_to_cpu(mod_elem->value);
465                         break;
466                 case AR_TKN_U32_MODULE_SRC_OP_PORT_ID:
467                         src_mod_op_port_id[0] = le32_to_cpu(mod_elem->value);
468                         break;
469                 case AR_TKN_U32_MODULE_SRC_OP_PORT_ID1:
470                         src_mod_op_port_id[1] = le32_to_cpu(mod_elem->value);
471                         break;
472                 case AR_TKN_U32_MODULE_SRC_OP_PORT_ID2:
473                         src_mod_op_port_id[2] = le32_to_cpu(mod_elem->value);
474                         break;
475                 case AR_TKN_U32_MODULE_SRC_OP_PORT_ID3:
476                         src_mod_op_port_id[3] = le32_to_cpu(mod_elem->value);
477                         break;
478                 case AR_TKN_U32_MODULE_SRC_OP_PORT_ID4:
479                         src_mod_op_port_id[4] = le32_to_cpu(mod_elem->value);
480                         break;
481                 case AR_TKN_U32_MODULE_SRC_OP_PORT_ID5:
482                         src_mod_op_port_id[5] = le32_to_cpu(mod_elem->value);
483                         break;
484                 case AR_TKN_U32_MODULE_SRC_OP_PORT_ID6:
485                         src_mod_op_port_id[6] = le32_to_cpu(mod_elem->value);
486                         break;
487                 case AR_TKN_U32_MODULE_SRC_OP_PORT_ID7:
488                         src_mod_op_port_id[7] = le32_to_cpu(mod_elem->value);
489                         break;
490                 case AR_TKN_U32_MODULE_DST_INSTANCE_ID:
491                         dst_mod_inst_id[0] = le32_to_cpu(mod_elem->value);
492                         break;
493                 case AR_TKN_U32_MODULE_DST_INSTANCE_ID1:
494                         dst_mod_inst_id[1] = le32_to_cpu(mod_elem->value);
495                         break;
496                 case AR_TKN_U32_MODULE_DST_INSTANCE_ID2:
497                         dst_mod_inst_id[2] = le32_to_cpu(mod_elem->value);
498                         break;
499                 case AR_TKN_U32_MODULE_DST_INSTANCE_ID3:
500                         dst_mod_inst_id[3] = le32_to_cpu(mod_elem->value);
501                         break;
502                 case AR_TKN_U32_MODULE_DST_INSTANCE_ID4:
503                         dst_mod_inst_id[4] = le32_to_cpu(mod_elem->value);
504                         break;
505                 case AR_TKN_U32_MODULE_DST_INSTANCE_ID5:
506                         dst_mod_inst_id[5] = le32_to_cpu(mod_elem->value);
507                         break;
508                 case AR_TKN_U32_MODULE_DST_INSTANCE_ID6:
509                         dst_mod_inst_id[6] = le32_to_cpu(mod_elem->value);
510                         break;
511                 case AR_TKN_U32_MODULE_DST_INSTANCE_ID7:
512                         dst_mod_inst_id[7] = le32_to_cpu(mod_elem->value);
513                         break;
514                 case AR_TKN_U32_MODULE_DST_IN_PORT_ID:
515                         dst_mod_ip_port_id[0] = le32_to_cpu(mod_elem->value);
516                         break;
517                 case AR_TKN_U32_MODULE_DST_IN_PORT_ID1:
518                         dst_mod_ip_port_id[1] = le32_to_cpu(mod_elem->value);
519                         break;
520                 case AR_TKN_U32_MODULE_DST_IN_PORT_ID2:
521                         dst_mod_ip_port_id[2] = le32_to_cpu(mod_elem->value);
522                         break;
523                 case AR_TKN_U32_MODULE_DST_IN_PORT_ID3:
524                         dst_mod_ip_port_id[3] = le32_to_cpu(mod_elem->value);
525                         break;
526                 case AR_TKN_U32_MODULE_DST_IN_PORT_ID4:
527                         dst_mod_ip_port_id[4] = le32_to_cpu(mod_elem->value);
528                         break;
529                 case AR_TKN_U32_MODULE_DST_IN_PORT_ID5:
530                         dst_mod_ip_port_id[5] = le32_to_cpu(mod_elem->value);
531                         break;
532                 case AR_TKN_U32_MODULE_DST_IN_PORT_ID6:
533                         dst_mod_ip_port_id[6] = le32_to_cpu(mod_elem->value);
534                         break;
535                 case AR_TKN_U32_MODULE_DST_IN_PORT_ID7:
536                         dst_mod_ip_port_id[7] = le32_to_cpu(mod_elem->value);
537                         break;
538                 default:
539                         break;
540
541                 }
542                 tkn_count++;
543                 mod_elem++;
544         }
545
546         if (mod) {
547                 int pn, id = 0;
548                 mod->module_id = module_id;
549                 mod->max_ip_port = max_ip_port;
550                 mod->max_op_port = max_op_port;
551                 mod->in_port = in_port;
552                 mod->out_port = out_port;
553                 mod->src_mod_inst_id = src_mod_inst_id;
554                 for (pn = 0; pn < mod->max_op_port; pn++) {
555                         if (src_mod_op_port_id[pn] && dst_mod_inst_id[pn] &&
556                             dst_mod_ip_port_id[pn]) {
557                                 mod->src_mod_op_port_id[id] = src_mod_op_port_id[pn];
558                                 mod->dst_mod_inst_id[id] = dst_mod_inst_id[pn];
559                                 mod->dst_mod_ip_port_id[id] = dst_mod_ip_port_id[pn];
560                                 id++;
561                                 mod->num_connections = id;
562                         }
563                 }
564         }
565
566         return mod;
567 }
568
569 static int audioreach_widget_load_module_common(struct snd_soc_component *component,
570                                                 int index, struct snd_soc_dapm_widget *w,
571                                                 struct snd_soc_tplg_dapm_widget *tplg_w)
572 {
573         struct q6apm *apm = dev_get_drvdata(component->dev);
574         struct audioreach_container *cont;
575         struct audioreach_sub_graph *sg;
576         struct audioreach_module *mod;
577         struct snd_soc_dobj *dobj;
578
579         sg = audioreach_parse_sg_tokens(apm, &tplg_w->priv);
580         if (IS_ERR(sg))
581                 return PTR_ERR(sg);
582
583         cont = audioreach_parse_cont_tokens(apm, sg, &tplg_w->priv);
584         if (IS_ERR(cont))
585                 return PTR_ERR(cont);
586
587         mod = audioreach_parse_common_tokens(apm, cont, &tplg_w->priv, w);
588         if (IS_ERR(mod))
589                 return PTR_ERR(mod);
590
591         dobj = &w->dobj;
592         dobj->private = mod;
593
594         return 0;
595 }
596
597 static int audioreach_widget_load_enc_dec_cnv(struct snd_soc_component *component,
598                                               int index, struct snd_soc_dapm_widget *w,
599                                               struct snd_soc_tplg_dapm_widget *tplg_w)
600 {
601         struct snd_soc_tplg_vendor_value_elem *mod_elem;
602         struct snd_soc_tplg_vendor_array *mod_array;
603         struct audioreach_module *mod;
604         struct snd_soc_dobj *dobj;
605         int tkn_count = 0;
606         int ret;
607
608         ret = audioreach_widget_load_module_common(component, index, w, tplg_w);
609         if (ret)
610                 return ret;
611
612         dobj = &w->dobj;
613         mod = dobj->private;
614         mod_array = audioreach_get_module_array(&tplg_w->priv);
615         mod_elem = mod_array->value;
616
617         while (tkn_count <= (le32_to_cpu(mod_array->num_elems) - 1)) {
618                 switch (le32_to_cpu(mod_elem->token)) {
619                 case AR_TKN_U32_MODULE_FMT_INTERLEAVE:
620                         mod->interleave_type = le32_to_cpu(mod_elem->value);
621                         break;
622                 case AR_TKN_U32_MODULE_FMT_SAMPLE_RATE:
623                         mod->rate = le32_to_cpu(mod_elem->value);
624                         break;
625                 case AR_TKN_U32_MODULE_FMT_BIT_DEPTH:
626                         mod->bit_depth = le32_to_cpu(mod_elem->value);
627                         break;
628                 default:
629                         break;
630                 }
631                 tkn_count++;
632                 mod_elem++;
633         }
634
635         return 0;
636 }
637
638 static int audioreach_widget_log_module_load(struct audioreach_module *mod,
639                                              struct snd_soc_tplg_vendor_array *mod_array)
640 {
641         struct snd_soc_tplg_vendor_value_elem *mod_elem;
642         int tkn_count = 0;
643
644         mod_elem = mod_array->value;
645
646         while (tkn_count <= (le32_to_cpu(mod_array->num_elems) - 1)) {
647                 switch (le32_to_cpu(mod_elem->token)) {
648
649                 case AR_TKN_U32_MODULE_LOG_CODE:
650                         mod->log_code = le32_to_cpu(mod_elem->value);
651                         break;
652                 case AR_TKN_U32_MODULE_LOG_TAP_POINT_ID:
653                         mod->log_tap_point_id = le32_to_cpu(mod_elem->value);
654                         break;
655                 case AR_TKN_U32_MODULE_LOG_MODE:
656                         mod->log_mode = le32_to_cpu(mod_elem->value);
657                         break;
658                 default:
659                         break;
660                 }
661                 tkn_count++;
662                 mod_elem++;
663         }
664
665         return 0;
666 }
667
668 static int audioreach_widget_dma_module_load(struct audioreach_module *mod,
669                                              struct snd_soc_tplg_vendor_array *mod_array)
670 {
671         struct snd_soc_tplg_vendor_value_elem *mod_elem;
672         int tkn_count = 0;
673
674         mod_elem = mod_array->value;
675
676         while (tkn_count <= (le32_to_cpu(mod_array->num_elems) - 1)) {
677                 switch (le32_to_cpu(mod_elem->token)) {
678                 case AR_TKN_U32_MODULE_HW_IF_IDX:
679                         mod->hw_interface_idx = le32_to_cpu(mod_elem->value);
680                         break;
681                 case AR_TKN_U32_MODULE_FMT_DATA:
682                         mod->data_format = le32_to_cpu(mod_elem->value);
683                         break;
684                 case AR_TKN_U32_MODULE_HW_IF_TYPE:
685                         mod->hw_interface_type = le32_to_cpu(mod_elem->value);
686                         break;
687                 default:
688                         break;
689                 }
690                 tkn_count++;
691                 mod_elem++;
692         }
693
694         return 0;
695 }
696
697 static int audioreach_widget_i2s_module_load(struct audioreach_module *mod,
698                                              struct snd_soc_tplg_vendor_array *mod_array)
699 {
700         struct snd_soc_tplg_vendor_value_elem *mod_elem;
701         int tkn_count = 0;
702
703         mod_elem = mod_array->value;
704
705         while (tkn_count <= (le32_to_cpu(mod_array->num_elems) - 1)) {
706                 switch (le32_to_cpu(mod_elem->token)) {
707                 case AR_TKN_U32_MODULE_HW_IF_IDX:
708                         mod->hw_interface_idx = le32_to_cpu(mod_elem->value);
709                         break;
710                 case AR_TKN_U32_MODULE_FMT_DATA:
711                         mod->data_format = le32_to_cpu(mod_elem->value);
712                         break;
713                 case AR_TKN_U32_MODULE_HW_IF_TYPE:
714                         mod->hw_interface_type = le32_to_cpu(mod_elem->value);
715                         break;
716                 case AR_TKN_U32_MODULE_SD_LINE_IDX:
717                         mod->sd_line_idx = le32_to_cpu(mod_elem->value);
718                         break;
719                 case AR_TKN_U32_MODULE_WS_SRC:
720                         mod->ws_src = le32_to_cpu(mod_elem->value);
721                         break;
722                 default:
723                         break;
724                 }
725                 tkn_count++;
726                 mod_elem++;
727         }
728
729         return 0;
730 }
731
732 static int audioreach_widget_load_buffer(struct snd_soc_component *component,
733                                          int index, struct snd_soc_dapm_widget *w,
734                                          struct snd_soc_tplg_dapm_widget *tplg_w)
735 {
736         struct snd_soc_tplg_vendor_array *mod_array;
737         struct audioreach_module *mod;
738         struct snd_soc_dobj *dobj;
739         int ret;
740
741         ret = audioreach_widget_load_module_common(component, index, w, tplg_w);
742         if (ret)
743                 return ret;
744
745         dobj = &w->dobj;
746         mod = dobj->private;
747
748         mod_array = audioreach_get_module_array(&tplg_w->priv);
749
750         switch (mod->module_id) {
751         case MODULE_ID_CODEC_DMA_SINK:
752         case MODULE_ID_CODEC_DMA_SOURCE:
753                 audioreach_widget_dma_module_load(mod, mod_array);
754                 break;
755         case MODULE_ID_DATA_LOGGING:
756                 audioreach_widget_log_module_load(mod, mod_array);
757                 break;
758         case MODULE_ID_I2S_SINK:
759         case MODULE_ID_I2S_SOURCE:
760                 audioreach_widget_i2s_module_load(mod, mod_array);
761                 break;
762         default:
763                 return -EINVAL;
764         }
765
766         return 0;
767 }
768
769 static int audioreach_widget_load_mixer(struct snd_soc_component *component,
770                                         int index, struct snd_soc_dapm_widget *w,
771                                         struct snd_soc_tplg_dapm_widget *tplg_w)
772 {
773         struct snd_soc_tplg_vendor_value_elem *w_elem;
774         struct snd_soc_tplg_vendor_array *w_array;
775         struct snd_ar_control *scontrol;
776         struct q6apm *data = dev_get_drvdata(component->dev);
777         struct snd_soc_dobj *dobj;
778         int tkn_count = 0;
779
780         w_array = &tplg_w->priv.array[0];
781
782         scontrol = kzalloc(sizeof(*scontrol), GFP_KERNEL);
783         if (!scontrol)
784                 return -ENOMEM;
785
786         scontrol->scomp = component;
787         dobj = &w->dobj;
788         dobj->private = scontrol;
789
790         w_elem = w_array->value;
791         while (tkn_count <= (le32_to_cpu(w_array->num_elems) - 1)) {
792                 switch (le32_to_cpu(w_elem->token)) {
793                 case AR_TKN_U32_SUB_GRAPH_INSTANCE_ID:
794                         scontrol->sgid = le32_to_cpu(w_elem->value);
795                         break;
796                 case AR_TKN_DAI_INDEX:
797                         scontrol->graph_id = le32_to_cpu(w_elem->value);
798                         break;
799                 default: /* ignore other tokens */
800                         break;
801                 }
802                 tkn_count++;
803                 w_elem++;
804         }
805
806         scontrol->w = w;
807         list_add_tail(&scontrol->node, &data->widget_list);
808
809         return 0;
810 }
811
812 static int audioreach_pga_event(struct snd_soc_dapm_widget *w,
813                                 struct snd_kcontrol *kcontrol, int event)
814
815 {
816         struct snd_soc_dapm_context *dapm = w->dapm;
817         struct snd_soc_component *c = snd_soc_dapm_to_component(dapm);
818         struct audioreach_module *mod = w->dobj.private;
819         struct q6apm *apm = dev_get_drvdata(c->dev);
820
821         switch (event) {
822         case SND_SOC_DAPM_POST_PMU:
823                 /* apply gain after power up of widget */
824                 audioreach_gain_set_vol_ctrl(apm, mod, mod->gain);
825                 break;
826         default:
827                 break;
828         }
829
830         return 0;
831 }
832
833 static const struct snd_soc_tplg_widget_events audioreach_widget_ops[] = {
834         { AR_PGA_DAPM_EVENT, audioreach_pga_event },
835 };
836
837 static int audioreach_widget_load_pga(struct snd_soc_component *component,
838                                       int index, struct snd_soc_dapm_widget *w,
839                                       struct snd_soc_tplg_dapm_widget *tplg_w)
840 {
841         struct audioreach_module *mod;
842         struct snd_soc_dobj *dobj;
843         int ret;
844
845         ret = audioreach_widget_load_module_common(component, index, w, tplg_w);
846         if (ret)
847                 return ret;
848
849         dobj = &w->dobj;
850         mod = dobj->private;
851         mod->gain = VOL_CTRL_DEFAULT_GAIN;
852
853         ret = snd_soc_tplg_widget_bind_event(w, audioreach_widget_ops,
854                                              ARRAY_SIZE(audioreach_widget_ops),
855                                              le16_to_cpu(tplg_w->event_type));
856         if (ret) {
857                 dev_err(component->dev, "matching event handlers NOT found for %d\n",
858                         le16_to_cpu(tplg_w->event_type));
859                 return -EINVAL;
860         }
861
862         return 0;
863 }
864
865 static int audioreach_widget_ready(struct snd_soc_component *component,
866                                    int index, struct snd_soc_dapm_widget *w,
867                                    struct snd_soc_tplg_dapm_widget *tplg_w)
868 {
869         switch (w->id) {
870         case snd_soc_dapm_aif_in:
871         case snd_soc_dapm_aif_out:
872                 audioreach_widget_load_buffer(component, index, w, tplg_w);
873                 break;
874         case snd_soc_dapm_decoder:
875         case snd_soc_dapm_encoder:
876         case snd_soc_dapm_src:
877                 audioreach_widget_load_enc_dec_cnv(component, index, w, tplg_w);
878                 break;
879         case snd_soc_dapm_buffer:
880                 audioreach_widget_load_buffer(component, index, w, tplg_w);
881                 break;
882         case snd_soc_dapm_mixer:
883                 return audioreach_widget_load_mixer(component, index, w, tplg_w);
884         case snd_soc_dapm_pga:
885                 return audioreach_widget_load_pga(component, index, w, tplg_w);
886         case snd_soc_dapm_dai_link:
887         case snd_soc_dapm_scheduler:
888         case snd_soc_dapm_out_drv:
889         default:
890                 dev_err(component->dev, "Widget type (0x%x) not yet supported\n", w->id);
891                 break;
892         }
893
894         return 0;
895 }
896
897 static int audioreach_widget_unload(struct snd_soc_component *scomp,
898                                     struct snd_soc_dobj *dobj)
899 {
900         struct snd_soc_dapm_widget *w = container_of(dobj, struct snd_soc_dapm_widget, dobj);
901         struct q6apm *apm = dev_get_drvdata(scomp->dev);
902         struct audioreach_container *cont;
903         struct audioreach_module *mod;
904
905         mod = dobj->private;
906         cont = mod->container;
907
908         if (w->id == snd_soc_dapm_mixer) {
909                 /* virtual widget */
910                 struct snd_ar_control *scontrol = dobj->private;
911
912                 list_del(&scontrol->node);
913                 kfree(scontrol);
914                 return 0;
915         }
916
917         mutex_lock(&apm->lock);
918         idr_remove(&apm->modules_idr, mod->instance_id);
919         cont->num_modules--;
920
921         list_del(&mod->node);
922         kfree(mod);
923         /* Graph Info has N sub-graphs, sub-graph has N containers, Container has N Modules */
924         if (list_empty(&cont->modules_list)) { /* if no modules in the container then remove it */
925                 struct audioreach_sub_graph *sg = cont->sub_graph;
926
927                 idr_remove(&apm->containers_idr, cont->container_id);
928                 list_del(&cont->node);
929                 sg->num_containers--;
930                 kfree(cont);
931                 /* check if there are no more containers in the sub graph and remove it */
932                 if (list_empty(&sg->container_list)) {
933                         struct audioreach_graph_info *info = sg->info;
934
935                         idr_remove(&apm->sub_graphs_idr, sg->sub_graph_id);
936                         list_del(&sg->node);
937                         info->num_sub_graphs--;
938                         kfree(sg);
939                         /* Check if there are no more sub-graphs left then remove graph info */
940                         if (list_empty(&info->sg_list)) {
941                                 idr_remove(&apm->graph_info_idr, info->id);
942                                 kfree(info);
943                         }
944                 }
945         }
946
947         mutex_unlock(&apm->lock);
948
949         return 0;
950 }
951
952 static struct snd_ar_control *audioreach_find_widget(struct snd_soc_component *comp,
953                                                      const char *name)
954 {
955         struct q6apm *apm = dev_get_drvdata(comp->dev);
956         struct snd_ar_control *control;
957
958         list_for_each_entry(control, &apm->widget_list, node) {
959                 if (control->w && !strcmp(name, control->w->name))
960                         return control;
961         }
962
963         return NULL;
964 }
965
966 static struct audioreach_module *audioreach_find_module(struct snd_soc_component *comp,
967                                                         const char *name)
968 {
969         struct q6apm *apm = dev_get_drvdata(comp->dev);
970         struct audioreach_module *module;
971         int id;
972
973         idr_for_each_entry(&apm->modules_idr, module, id) {
974                 if (!strcmp(name, module->widget->name))
975                         return module;
976         }
977
978         return NULL;
979 }
980
981 static int audioreach_route_load(struct snd_soc_component *scomp, int index,
982                                  struct snd_soc_dapm_route *route)
983 {
984         struct audioreach_module *src_module, *sink_module;
985         struct snd_ar_control *control;
986         struct snd_soc_dapm_widget *w;
987         int i;
988
989         /* check if these are actual modules */
990         src_module = audioreach_find_module(scomp, route->source);
991         sink_module = audioreach_find_module(scomp, route->sink);
992
993         if (sink_module && !src_module) {
994                 control = audioreach_find_widget(scomp, route->source);
995                 if (control)
996                         control->module_instance_id = sink_module->instance_id;
997
998         } else if (!sink_module && src_module && route->control) {
999                 /* check if this is a virtual mixer */
1000                 control = audioreach_find_widget(scomp, route->sink);
1001                 if (!control || !control->w)
1002                         return 0;
1003
1004                 w = control->w;
1005
1006                 for (i = 0; i < w->num_kcontrols; i++) {
1007                         if (!strcmp(route->control, w->kcontrol_news[i].name)) {
1008                                 struct soc_mixer_control *sm;
1009                                 struct snd_soc_dobj *dobj;
1010                                 struct snd_ar_control *scontrol;
1011
1012                                 sm = (struct soc_mixer_control *)w->kcontrol_news[i].private_value;
1013                                 dobj = &sm->dobj;
1014                                 scontrol = dobj->private;
1015                                 scontrol->module_instance_id = src_module->instance_id;
1016                         }
1017                 }
1018
1019         }
1020
1021         return 0;
1022 }
1023
1024 static int audioreach_route_unload(struct snd_soc_component *scomp,
1025                                    struct snd_soc_dobj *dobj)
1026 {
1027         return 0;
1028 }
1029
1030 static int audioreach_tplg_complete(struct snd_soc_component *component)
1031 {
1032         /* TBD */
1033         return 0;
1034 }
1035
1036 /* DAI link - used for any driver specific init */
1037 static int audioreach_link_load(struct snd_soc_component *component, int index,
1038                                 struct snd_soc_dai_link *link,
1039                                 struct snd_soc_tplg_link_config *cfg)
1040 {
1041         link->nonatomic = true;
1042         link->dynamic = true;
1043         link->platforms->name = NULL;
1044         link->platforms->of_node = of_get_compatible_child(component->dev->of_node,
1045                                                            "qcom,q6apm-dais");
1046         return 0;
1047 }
1048
1049 static void audioreach_connect_sub_graphs(struct q6apm *apm,
1050                                           struct snd_ar_control *m1,
1051                                           struct snd_ar_control *m2,
1052                                           bool connect)
1053 {
1054         struct audioreach_graph_info *info;
1055
1056         mutex_lock(&apm->lock);
1057         info = idr_find(&apm->graph_info_idr, m2->graph_id);
1058         mutex_unlock(&apm->lock);
1059
1060         if (connect) {
1061                 info->src_mod_inst_id = m1->module_instance_id;
1062                 info->src_mod_op_port_id = 1;
1063                 info->dst_mod_inst_id = m2->module_instance_id;
1064                 info->dst_mod_ip_port_id = 2;
1065
1066         } else {
1067                 info->src_mod_inst_id = 0;
1068                 info->src_mod_op_port_id = 0;
1069                 info->dst_mod_inst_id = 0;
1070                 info->dst_mod_ip_port_id = 0;
1071         }
1072 }
1073
1074 static bool audioreach_is_vmixer_connected(struct q6apm *apm,
1075                                            struct snd_ar_control *m1,
1076                                            struct snd_ar_control *m2)
1077 {
1078         struct audioreach_graph_info *info;
1079
1080         mutex_lock(&apm->lock);
1081         info = idr_find(&apm->graph_info_idr, m2->graph_id);
1082         mutex_unlock(&apm->lock);
1083
1084         if (info->dst_mod_inst_id == m2->module_instance_id &&
1085             info->src_mod_inst_id == m1->module_instance_id)
1086                 return true;
1087
1088         return false;
1089 }
1090
1091 static int audioreach_get_audio_mixer(struct snd_kcontrol *kcontrol,
1092                                       struct snd_ctl_elem_value *ucontrol)
1093 {
1094         struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value;
1095         struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
1096         struct snd_soc_dapm_widget *dw = snd_soc_dapm_kcontrol_widget(kcontrol);
1097         struct snd_soc_component *c = snd_soc_dapm_to_component(dapm);
1098         struct snd_ar_control *dapm_scontrol = dw->dobj.private;
1099         struct snd_ar_control *scontrol = mc->dobj.private;
1100         struct q6apm *data = dev_get_drvdata(c->dev);
1101         bool connected;
1102
1103         connected = audioreach_is_vmixer_connected(data, scontrol, dapm_scontrol);
1104         if (connected)
1105                 ucontrol->value.integer.value[0] = 1;
1106         else
1107                 ucontrol->value.integer.value[0] = 0;
1108
1109         return 0;
1110 }
1111
1112 static int audioreach_put_audio_mixer(struct snd_kcontrol *kcontrol,
1113                                       struct snd_ctl_elem_value *ucontrol)
1114 {
1115         struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value;
1116         struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
1117         struct snd_soc_dapm_widget *dw = snd_soc_dapm_kcontrol_widget(kcontrol);
1118         struct snd_soc_component *c = snd_soc_dapm_to_component(dapm);
1119         struct snd_ar_control *dapm_scontrol = dw->dobj.private;
1120         struct snd_ar_control *scontrol = mc->dobj.private;
1121         struct q6apm *data = dev_get_drvdata(c->dev);
1122
1123         if (ucontrol->value.integer.value[0]) {
1124                 audioreach_connect_sub_graphs(data, scontrol, dapm_scontrol, true);
1125                 snd_soc_dapm_mixer_update_power(dapm, kcontrol, 1, NULL);
1126         } else {
1127                 audioreach_connect_sub_graphs(data, scontrol, dapm_scontrol, false);
1128                 snd_soc_dapm_mixer_update_power(dapm, kcontrol, 0, NULL);
1129         }
1130         return 0;
1131 }
1132
1133 static int audioreach_get_vol_ctrl_audio_mixer(struct snd_kcontrol *kcontrol,
1134                                                struct snd_ctl_elem_value *ucontrol)
1135 {
1136         struct snd_soc_dapm_widget *dw = snd_soc_dapm_kcontrol_widget(kcontrol);
1137         struct audioreach_module *mod = dw->dobj.private;
1138
1139         ucontrol->value.integer.value[0] = mod->gain;
1140
1141         return 0;
1142 }
1143
1144 static int audioreach_put_vol_ctrl_audio_mixer(struct snd_kcontrol *kcontrol,
1145                                                struct snd_ctl_elem_value *ucontrol)
1146 {
1147         struct snd_soc_dapm_widget *dw = snd_soc_dapm_kcontrol_widget(kcontrol);
1148         struct audioreach_module *mod = dw->dobj.private;
1149
1150         mod->gain = ucontrol->value.integer.value[0];
1151
1152         return 1;
1153 }
1154
1155 static int audioreach_control_load_mix(struct snd_soc_component *scomp,
1156                                        struct snd_ar_control *scontrol,
1157                                        struct snd_kcontrol_new *kc,
1158                                        struct snd_soc_tplg_ctl_hdr *hdr)
1159 {
1160         struct snd_soc_tplg_vendor_value_elem *c_elem;
1161         struct snd_soc_tplg_vendor_array *c_array;
1162         struct snd_soc_tplg_mixer_control *mc;
1163         int tkn_count = 0;
1164
1165         mc = container_of(hdr, struct snd_soc_tplg_mixer_control, hdr);
1166         c_array = (struct snd_soc_tplg_vendor_array *)mc->priv.data;
1167
1168         c_elem = c_array->value;
1169
1170         while (tkn_count <= (le32_to_cpu(c_array->num_elems) - 1)) {
1171                 switch (le32_to_cpu(c_elem->token)) {
1172                 case AR_TKN_U32_SUB_GRAPH_INSTANCE_ID:
1173                         scontrol->sgid = le32_to_cpu(c_elem->value);
1174                         break;
1175                 case AR_TKN_DAI_INDEX:
1176                         scontrol->graph_id = le32_to_cpu(c_elem->value);
1177                         break;
1178                 default:
1179                         /* Ignore other tokens */
1180                         break;
1181                 }
1182                 c_elem++;
1183                 tkn_count++;
1184         }
1185
1186         return 0;
1187 }
1188
1189 static int audioreach_control_load(struct snd_soc_component *scomp, int index,
1190                                    struct snd_kcontrol_new *kc,
1191                                    struct snd_soc_tplg_ctl_hdr *hdr)
1192 {
1193         struct snd_ar_control *scontrol;
1194         struct soc_mixer_control *sm;
1195         struct snd_soc_dobj *dobj;
1196         int ret = 0;
1197
1198         scontrol = kzalloc(sizeof(*scontrol), GFP_KERNEL);
1199         if (!scontrol)
1200                 return -ENOMEM;
1201
1202         scontrol->scomp = scomp;
1203
1204         switch (le32_to_cpu(hdr->ops.get)) {
1205         case SND_SOC_AR_TPLG_FE_BE_GRAPH_CTL_MIX:
1206                 sm = (struct soc_mixer_control *)kc->private_value;
1207                 dobj = &sm->dobj;
1208                 ret = audioreach_control_load_mix(scomp, scontrol, kc, hdr);
1209                 break;
1210         case SND_SOC_AR_TPLG_VOL_CTL:
1211                 sm = (struct soc_mixer_control *)kc->private_value;
1212                 dobj = &sm->dobj;
1213                 break;
1214         default:
1215                 dev_warn(scomp->dev, "control type not supported %d:%d:%d\n",
1216                          hdr->ops.get, hdr->ops.put, hdr->ops.info);
1217                 kfree(scontrol);
1218                 return -EINVAL;
1219         }
1220
1221         dobj->private = scontrol;
1222         return ret;
1223 }
1224
1225 static int audioreach_control_unload(struct snd_soc_component *scomp,
1226                                      struct snd_soc_dobj *dobj)
1227 {
1228         struct snd_ar_control *scontrol = dobj->private;
1229
1230         kfree(scontrol);
1231
1232         return 0;
1233 }
1234
1235 static const struct snd_soc_tplg_kcontrol_ops audioreach_io_ops[] = {
1236         {SND_SOC_AR_TPLG_FE_BE_GRAPH_CTL_MIX, audioreach_get_audio_mixer,
1237                 audioreach_put_audio_mixer, snd_soc_info_volsw},
1238         {SND_SOC_AR_TPLG_VOL_CTL, audioreach_get_vol_ctrl_audio_mixer,
1239                 audioreach_put_vol_ctrl_audio_mixer, snd_soc_info_volsw},
1240 };
1241
1242 static struct snd_soc_tplg_ops audioreach_tplg_ops  = {
1243         .io_ops = audioreach_io_ops,
1244         .io_ops_count = ARRAY_SIZE(audioreach_io_ops),
1245
1246         .control_load   = audioreach_control_load,
1247         .control_unload = audioreach_control_unload,
1248
1249         .widget_ready = audioreach_widget_ready,
1250         .widget_unload = audioreach_widget_unload,
1251
1252         .complete = audioreach_tplg_complete,
1253         .link_load = audioreach_link_load,
1254
1255         .dapm_route_load        = audioreach_route_load,
1256         .dapm_route_unload      = audioreach_route_unload,
1257 };
1258
1259 int audioreach_tplg_init(struct snd_soc_component *component)
1260 {
1261         struct snd_soc_card *card = component->card;
1262         struct device *dev = component->dev;
1263         const struct firmware *fw;
1264         char *tplg_fw_name;
1265         int ret;
1266
1267         /* Inline with Qualcomm UCM configs and linux-firmware path */
1268         tplg_fw_name = kasprintf(GFP_KERNEL, "/*(DEBLOBBED)*/", card->driver_name, card->name);
1269         if (!tplg_fw_name)
1270                 return -ENOMEM;
1271
1272         ret = reject_firmware(&fw, tplg_fw_name, dev);
1273         if (ret < 0) {
1274                 dev_err(dev, "tplg firmware loading %s failed %d \n", tplg_fw_name, ret);
1275                 goto err;
1276         }
1277
1278         ret = snd_soc_tplg_component_load(component, &audioreach_tplg_ops, fw);
1279         if (ret < 0) {
1280                 if (ret != -EPROBE_DEFER)
1281                         dev_err(dev, "tplg component load failed: %d\n", ret);
1282         }
1283
1284         release_firmware(fw);
1285 err:
1286         kfree(tplg_fw_name);
1287
1288         return ret;
1289 }
1290 EXPORT_SYMBOL_GPL(audioreach_tplg_init);