1
2
3
4
5
6
7
8
9#include <linux/clk.h>
10#include <linux/device.h>
11#include <linux/gpio/consumer.h>
12#include <linux/module.h>
13#include <linux/of.h>
14#include <linux/of_graph.h>
15#include <linux/platform_device.h>
16#include <linux/string.h>
17#include <sound/graph_card.h>
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225enum graph_type {
226 GRAPH_NORMAL,
227 GRAPH_DPCM,
228 GRAPH_C2C,
229
230 GRAPH_MULTI,
231};
232
233#define GRAPH_NODENAME_MULTI "multi"
234#define GRAPH_NODENAME_DPCM "dpcm"
235#define GRAPH_NODENAME_C2C "codec2codec"
236
237#define graph_ret(priv, ret) _graph_ret(priv, __func__, ret)
238static inline int _graph_ret(struct simple_util_priv *priv,
239 const char *func, int ret)
240{
241 return snd_soc_ret(simple_priv_to_dev(priv), ret, "at %s()\n", func);
242}
243
244#define ep_to_port(ep) of_get_parent(ep)
245static struct device_node *port_to_ports(struct device_node *port)
246{
247 struct device_node *ports = of_get_parent(port);
248
249 if (!of_node_name_eq(ports, "ports")) {
250 of_node_put(ports);
251 return NULL;
252 }
253 return ports;
254}
255
256static enum graph_type __graph_get_type(struct device_node *lnk)
257{
258 struct device_node *np, *parent_np;
259 enum graph_type ret;
260
261
262
263
264
265
266
267
268
269 np = of_get_parent(lnk);
270 if (of_node_name_eq(np, "ports")) {
271 parent_np = of_get_parent(np);
272 of_node_put(np);
273 np = parent_np;
274 }
275
276 if (of_node_name_eq(np, GRAPH_NODENAME_MULTI)) {
277 ret = GRAPH_MULTI;
278 fw_devlink_purge_absent_suppliers(&np->fwnode);
279 goto out_put;
280 }
281
282 if (of_node_name_eq(np, GRAPH_NODENAME_DPCM)) {
283 ret = GRAPH_DPCM;
284 fw_devlink_purge_absent_suppliers(&np->fwnode);
285 goto out_put;
286 }
287
288 if (of_node_name_eq(np, GRAPH_NODENAME_C2C)) {
289 ret = GRAPH_C2C;
290 fw_devlink_purge_absent_suppliers(&np->fwnode);
291 goto out_put;
292 }
293
294 ret = GRAPH_NORMAL;
295
296out_put:
297 of_node_put(np);
298 return ret;
299
300}
301
302static enum graph_type graph_get_type(struct simple_util_priv *priv,
303 struct device_node *lnk)
304{
305 enum graph_type type = __graph_get_type(lnk);
306
307
308 if (type == GRAPH_MULTI)
309 type = GRAPH_NORMAL;
310
311#ifdef DEBUG
312 {
313 struct device *dev = simple_priv_to_dev(priv);
314 const char *str = "Normal";
315
316 switch (type) {
317 case GRAPH_DPCM:
318 if (graph_util_is_ports0(lnk))
319 str = "DPCM Front-End";
320 else
321 str = "DPCM Back-End";
322 break;
323 case GRAPH_C2C:
324 str = "Codec2Codec";
325 break;
326 default:
327 break;
328 }
329
330 dev_dbg(dev, "%pOF (%s)", lnk, str);
331 }
332#endif
333 return type;
334}
335
336static int graph_lnk_is_multi(struct device_node *lnk)
337{
338 return __graph_get_type(lnk) == GRAPH_MULTI;
339}
340
341static struct device_node *graph_get_next_multi_ep(struct device_node **port, int idx)
342{
343 struct device_node *ports __free(device_node) = port_to_ports(*port);
344 struct device_node *rep = NULL;
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368 of_node_put(*port);
369
370 *port = of_graph_get_port_by_id(ports, idx);
371 if (*port) {
372 struct device_node *ep __free(device_node) = of_graph_get_next_port_endpoint(*port, NULL);
373
374 rep = of_graph_get_remote_endpoint(ep);
375 }
376
377 return rep;
378}
379
380static const struct snd_soc_ops graph_ops = {
381 .startup = simple_util_startup,
382 .shutdown = simple_util_shutdown,
383 .hw_params = simple_util_hw_params,
384};
385
386static void graph_parse_convert(struct device_node *ep,
387 struct simple_dai_props *props)
388{
389 struct device_node *port __free(device_node) = ep_to_port(ep);
390 struct device_node *ports __free(device_node) = port_to_ports(port);
391 struct simple_util_data *adata = &props->adata;
392
393 simple_util_parse_convert(ports, NULL, adata);
394 simple_util_parse_convert(port, NULL, adata);
395 simple_util_parse_convert(ep, NULL, adata);
396}
397
398static int __graph_parse_node(struct simple_util_priv *priv,
399 enum graph_type gtype,
400 struct device_node *ep,
401 struct link_info *li,
402 int is_cpu, int idx)
403{
404 struct device *dev = simple_priv_to_dev(priv);
405 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link);
406 struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link);
407 struct snd_soc_dai_link_component *dlc;
408 struct simple_util_dai *dai;
409 int ret, is_single_links = 0;
410
411 if (is_cpu) {
412 dlc = snd_soc_link_to_cpu(dai_link, idx);
413 dai = simple_props_to_dai_cpu(dai_props, idx);
414 } else {
415 dlc = snd_soc_link_to_codec(dai_link, idx);
416 dai = simple_props_to_dai_codec(dai_props, idx);
417 }
418
419 ret = graph_util_parse_dai(priv, ep, dlc, &is_single_links);
420 if (ret < 0)
421 goto end;
422
423 ret = simple_util_parse_tdm(ep, dai);
424 if (ret < 0)
425 goto end;
426
427 ret = simple_util_parse_tdm_width_map(priv, ep, dai);
428 if (ret < 0)
429 goto end;
430
431 ret = simple_util_parse_clk(dev, ep, dai, dlc);
432 if (ret < 0)
433 goto end;
434
435
436
437
438 if (!dai_link->name) {
439 struct snd_soc_dai_link_component *cpus = dlc;
440 struct snd_soc_dai_link_component *codecs = snd_soc_link_to_codec(dai_link, idx);
441 char *cpu_multi = "";
442 char *codec_multi = "";
443
444 if (dai_link->num_cpus > 1)
445 cpu_multi = "_multi";
446 if (dai_link->num_codecs > 1)
447 codec_multi = "_multi";
448
449 switch (gtype) {
450 case GRAPH_NORMAL:
451
452 if (is_cpu)
453 simple_util_set_dailink_name(priv, dai_link, "%s%s-%s%s",
454 cpus->dai_name, cpu_multi,
455 codecs->dai_name, codec_multi);
456 break;
457 case GRAPH_DPCM:
458 if (is_cpu)
459 simple_util_set_dailink_name(priv, dai_link, "fe.%pOFP.%s%s",
460 cpus->of_node, cpus->dai_name, cpu_multi);
461 else
462 simple_util_set_dailink_name(priv, dai_link, "be.%pOFP.%s%s",
463 codecs->of_node, codecs->dai_name, codec_multi);
464 break;
465 case GRAPH_C2C:
466
467 if (is_cpu)
468 simple_util_set_dailink_name(priv, dai_link, "c2c.%s%s-%s%s",
469 cpus->dai_name, cpu_multi,
470 codecs->dai_name, codec_multi);
471 break;
472 default:
473 break;
474 }
475 }
476
477
478
479
480
481 if (!is_cpu && gtype == GRAPH_DPCM) {
482 struct snd_soc_dai_link_component *codecs = snd_soc_link_to_codec(dai_link, idx);
483 struct snd_soc_codec_conf *cconf = simple_props_to_codec_conf(dai_props, idx);
484 struct device_node *rport __free(device_node) = ep_to_port(ep);
485 struct device_node *rports __free(device_node) = port_to_ports(rport);
486
487 snd_soc_of_parse_node_prefix(rports, cconf, codecs->of_node, "prefix");
488 snd_soc_of_parse_node_prefix(rport, cconf, codecs->of_node, "prefix");
489 }
490
491 if (is_cpu) {
492 struct snd_soc_dai_link_component *cpus = dlc;
493 struct snd_soc_dai_link_component *platforms = snd_soc_link_to_platform(dai_link, idx);
494
495 simple_util_canonicalize_cpu(cpus, is_single_links);
496 simple_util_canonicalize_platform(platforms, cpus);
497 }
498end:
499 return graph_ret(priv, ret);
500}
501
502static int graph_parse_node_multi_nm(struct simple_util_priv *priv,
503 struct snd_soc_dai_link *dai_link,
504 int *nm_idx, int cpu_idx,
505 struct device_node *mcpu_port)
506{
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537 struct device_node *mcpu_ep __free(device_node) = of_graph_get_next_port_endpoint(mcpu_port, NULL);
538 struct device_node *mcpu_ports __free(device_node) = port_to_ports(mcpu_port);
539 struct device_node *mcpu_port_top __free(device_node) = of_graph_get_next_port(mcpu_ports, NULL);
540 struct device_node *mcpu_ep_top __free(device_node) = of_graph_get_next_port_endpoint(mcpu_port_top, NULL);
541 struct device_node *mcodec_ep_top __free(device_node) = of_graph_get_remote_endpoint(mcpu_ep_top);
542 struct device_node *mcodec_port_top __free(device_node) = ep_to_port(mcodec_ep_top);
543 struct device_node *mcodec_ports __free(device_node) = port_to_ports(mcodec_port_top);
544 int nm_max = max(dai_link->num_cpus, dai_link->num_codecs);
545 int ret = -EINVAL;
546
547 if (cpu_idx > dai_link->num_cpus)
548 goto end;
549
550 for_each_of_graph_port_endpoint(mcpu_port, mcpu_ep_n) {
551 int codec_idx = 0;
552
553
554 if (mcpu_ep_n == mcpu_ep)
555 continue;
556
557 if (*nm_idx > nm_max)
558 break;
559
560 struct device_node *mcodec_ep_n __free(device_node) = of_graph_get_remote_endpoint(mcpu_ep_n);
561 struct device_node *mcodec_port __free(device_node) = ep_to_port(mcodec_ep_n);
562
563 ret = -EINVAL;
564 if (mcodec_ports != port_to_ports(mcodec_port))
565 break;
566
567 for_each_of_graph_port(mcodec_ports, mcodec_port_i) {
568
569
570 if (mcodec_port_top == mcodec_port_i)
571 continue;
572
573 if (codec_idx > dai_link->num_codecs)
574 break;
575
576 if (mcodec_port_i == mcodec_port) {
577 dai_link->ch_maps[*nm_idx].cpu = cpu_idx;
578 dai_link->ch_maps[*nm_idx].codec = codec_idx;
579
580 (*nm_idx)++;
581 ret = 0;
582 break;
583 }
584 codec_idx++;
585 }
586 if (ret < 0)
587 break;
588 }
589end:
590 return graph_ret(priv, ret);
591}
592
593static int graph_parse_node_multi(struct simple_util_priv *priv,
594 enum graph_type gtype,
595 struct device_node *port,
596 struct link_info *li, int is_cpu)
597{
598 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link);
599 struct device *dev = simple_priv_to_dev(priv);
600 int ret = -ENOMEM;
601 int nm_idx = 0;
602 int nm_max = max(dai_link->num_cpus, dai_link->num_codecs);
603
604
605
606
607
608 if (gtype != GRAPH_DPCM && !dai_link->ch_maps &&
609 dai_link->num_cpus > 1 && dai_link->num_codecs > 1 &&
610 dai_link->num_cpus != dai_link->num_codecs) {
611
612 dai_link->ch_maps = devm_kcalloc(dev, nm_max,
613 sizeof(struct snd_soc_dai_link_ch_map), GFP_KERNEL);
614 if (!dai_link->ch_maps)
615 goto multi_err;
616 }
617
618 for (int idx = 0;; idx++) {
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634 struct device_node *ep __free(device_node) = graph_get_next_multi_ep(&port, idx + 1);
635 if (!ep)
636 break;
637
638 ret = __graph_parse_node(priv, gtype, ep, li, is_cpu, idx);
639 if (ret < 0)
640 goto multi_err;
641
642
643 if (is_cpu && dai_link->ch_maps) {
644 ret = graph_parse_node_multi_nm(priv, dai_link, &nm_idx, idx, port);
645 if (ret < 0)
646 goto multi_err;
647 }
648 }
649
650 if (is_cpu && dai_link->ch_maps && (nm_idx != nm_max))
651 ret = -EINVAL;
652
653multi_err:
654 return graph_ret(priv, ret);
655}
656
657static int graph_parse_node_single(struct simple_util_priv *priv,
658 enum graph_type gtype,
659 struct device_node *ep,
660 struct link_info *li, int is_cpu)
661{
662 return graph_ret(priv, __graph_parse_node(priv, gtype, ep, li, is_cpu, 0));
663}
664
665static int graph_parse_node(struct simple_util_priv *priv,
666 enum graph_type gtype,
667 struct device_node *ep,
668 struct link_info *li, int is_cpu)
669{
670 struct device_node *port __free(device_node) = ep_to_port(ep);
671 int ret;
672
673 if (graph_lnk_is_multi(port))
674 ret = graph_parse_node_multi(priv, gtype, port, li, is_cpu);
675 else
676 ret = graph_parse_node_single(priv, gtype, ep, li, is_cpu);
677
678 return graph_ret(priv, ret);
679}
680
681static void graph_parse_daifmt(struct device_node *node, unsigned int *daifmt)
682{
683 unsigned int fmt;
684
685 if (!node)
686 return;
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706#define update_daifmt(name) \
707 if (!(*daifmt & SND_SOC_DAIFMT_##name##_MASK) && \
708 (fmt & SND_SOC_DAIFMT_##name##_MASK)) \
709 *daifmt |= fmt & SND_SOC_DAIFMT_##name##_MASK
710
711
712
713
714
715
716
717 fmt = snd_soc_daifmt_parse_format(node, NULL);
718 update_daifmt(FORMAT);
719 update_daifmt(CLOCK);
720 update_daifmt(INV);
721}
722
723static unsigned int graph_parse_bitframe(struct device_node *ep)
724{
725 struct device_node *port __free(device_node) = ep_to_port(ep);
726 struct device_node *ports __free(device_node) = port_to_ports(port);
727
728 return snd_soc_daifmt_clock_provider_from_bitmap(
729 snd_soc_daifmt_parse_clock_provider_as_bitmap(ep, NULL) |
730 snd_soc_daifmt_parse_clock_provider_as_bitmap(port, NULL) |
731 snd_soc_daifmt_parse_clock_provider_as_bitmap(ports, NULL));
732}
733
734static void graph_link_init(struct simple_util_priv *priv,
735 struct device_node *lnk,
736 struct device_node *ep_cpu,
737 struct device_node *ep_codec,
738 struct link_info *li,
739 int is_cpu_node)
740{
741 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link);
742 struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link);
743 struct device_node *port_cpu = ep_to_port(ep_cpu);
744 struct device_node *port_codec = ep_to_port(ep_codec);
745 struct device_node *multi_cpu_port = NULL, *multi_codec_port = NULL;
746 struct snd_soc_dai_link_component *dlc;
747 unsigned int daifmt = 0;
748 bool playback_only = 0, capture_only = 0;
749 enum snd_soc_trigger_order trigger_start = SND_SOC_TRIGGER_ORDER_DEFAULT;
750 enum snd_soc_trigger_order trigger_stop = SND_SOC_TRIGGER_ORDER_DEFAULT;
751 int multi_cpu_port_idx = 1, multi_codec_port_idx = 1;
752 int i;
753
754 if (graph_lnk_is_multi(port_cpu)) {
755 multi_cpu_port = port_cpu;
756 ep_cpu = graph_get_next_multi_ep(&multi_cpu_port, multi_cpu_port_idx++);
757 of_node_put(port_cpu);
758 port_cpu = ep_to_port(ep_cpu);
759 } else {
760 of_node_get(ep_cpu);
761 }
762 struct device_node *ports_cpu __free(device_node) = port_to_ports(port_cpu);
763
764 if (graph_lnk_is_multi(port_codec)) {
765 multi_codec_port = port_codec;
766 ep_codec = graph_get_next_multi_ep(&multi_codec_port, multi_codec_port_idx++);
767 of_node_put(port_codec);
768 port_codec = ep_to_port(ep_codec);
769 } else {
770 of_node_get(ep_codec);
771 }
772 struct device_node *ports_codec __free(device_node) = port_to_ports(port_codec);
773
774 graph_parse_daifmt(ep_cpu, &daifmt);
775 graph_parse_daifmt(ep_codec, &daifmt);
776 graph_parse_daifmt(port_cpu, &daifmt);
777 graph_parse_daifmt(port_codec, &daifmt);
778 graph_parse_daifmt(ports_cpu, &daifmt);
779 graph_parse_daifmt(ports_codec, &daifmt);
780 graph_parse_daifmt(lnk, &daifmt);
781
782 graph_util_parse_link_direction(lnk, &playback_only, &capture_only);
783 graph_util_parse_link_direction(ports_cpu, &playback_only, &capture_only);
784 graph_util_parse_link_direction(ports_codec, &playback_only, &capture_only);
785 graph_util_parse_link_direction(port_cpu, &playback_only, &capture_only);
786 graph_util_parse_link_direction(port_codec, &playback_only, &capture_only);
787 graph_util_parse_link_direction(ep_cpu, &playback_only, &capture_only);
788 graph_util_parse_link_direction(ep_codec, &playback_only, &capture_only);
789
790 of_property_read_u32(lnk, "mclk-fs", &dai_props->mclk_fs);
791 of_property_read_u32(ports_cpu, "mclk-fs", &dai_props->mclk_fs);
792 of_property_read_u32(ports_codec, "mclk-fs", &dai_props->mclk_fs);
793 of_property_read_u32(port_cpu, "mclk-fs", &dai_props->mclk_fs);
794 of_property_read_u32(port_codec, "mclk-fs", &dai_props->mclk_fs);
795 of_property_read_u32(ep_cpu, "mclk-fs", &dai_props->mclk_fs);
796 of_property_read_u32(ep_codec, "mclk-fs", &dai_props->mclk_fs);
797
798 graph_util_parse_trigger_order(priv, lnk, &trigger_start, &trigger_stop);
799 graph_util_parse_trigger_order(priv, ports_cpu, &trigger_start, &trigger_stop);
800 graph_util_parse_trigger_order(priv, ports_codec, &trigger_start, &trigger_stop);
801 graph_util_parse_trigger_order(priv, port_cpu, &trigger_start, &trigger_stop);
802 graph_util_parse_trigger_order(priv, port_cpu, &trigger_start, &trigger_stop);
803 graph_util_parse_trigger_order(priv, ep_cpu, &trigger_start, &trigger_stop);
804 graph_util_parse_trigger_order(priv, ep_codec, &trigger_start, &trigger_stop);
805
806 for_each_link_cpus(dai_link, i, dlc) {
807 dlc->ext_fmt = graph_parse_bitframe(ep_cpu);
808
809 if (multi_cpu_port)
810 ep_cpu = graph_get_next_multi_ep(&multi_cpu_port, multi_cpu_port_idx++);
811 }
812
813 for_each_link_codecs(dai_link, i, dlc) {
814 dlc->ext_fmt = graph_parse_bitframe(ep_codec);
815
816 if (multi_codec_port)
817 ep_codec = graph_get_next_multi_ep(&multi_codec_port, multi_codec_port_idx++);
818 }
819
820
821
822 dai_link->playback_only = playback_only;
823 dai_link->capture_only = capture_only;
824
825 dai_link->trigger_start = trigger_start;
826 dai_link->trigger_stop = trigger_stop;
827
828 dai_link->dai_fmt = daifmt;
829 dai_link->init = simple_util_dai_init;
830 dai_link->ops = &graph_ops;
831 if (priv->ops)
832 dai_link->ops = priv->ops;
833
834 of_node_put(port_cpu);
835 of_node_put(port_codec);
836 of_node_put(ep_cpu);
837 of_node_put(ep_codec);
838}
839
840int audio_graph2_link_normal(struct simple_util_priv *priv,
841 struct device_node *lnk,
842 struct link_info *li)
843{
844 struct device_node *cpu_port = lnk;
845 struct device_node *cpu_ep __free(device_node) = of_graph_get_next_port_endpoint(cpu_port, NULL);
846 struct device_node *codec_ep __free(device_node) = of_graph_get_remote_endpoint(cpu_ep);
847 int ret;
848
849
850
851
852
853
854 ret = graph_parse_node(priv, GRAPH_NORMAL, codec_ep, li, 0);
855 if (ret < 0)
856 goto end;
857
858
859
860
861 ret = graph_parse_node(priv, GRAPH_NORMAL, cpu_ep, li, 1);
862 if (ret < 0)
863 goto end;
864
865 graph_link_init(priv, lnk, cpu_ep, codec_ep, li, 1);
866
867end:
868 return graph_ret(priv, ret);
869}
870EXPORT_SYMBOL_GPL(audio_graph2_link_normal);
871
872int audio_graph2_link_dpcm(struct simple_util_priv *priv,
873 struct device_node *lnk,
874 struct link_info *li)
875{
876 struct device_node *ep __free(device_node) = of_graph_get_next_port_endpoint(lnk, NULL);
877 struct device_node *rep __free(device_node) = of_graph_get_remote_endpoint(ep);
878 struct device_node *cpu_ep = NULL;
879 struct device_node *codec_ep = NULL;
880 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link);
881 struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link);
882 int is_cpu = graph_util_is_ports0(lnk);
883 int ret;
884
885 if (is_cpu) {
886 cpu_ep = rep;
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912 dai_link->dynamic = 1;
913 dai_link->dpcm_merged_format = 1;
914
915 ret = graph_parse_node(priv, GRAPH_DPCM, cpu_ep, li, 1);
916 if (ret)
917 return ret;
918
919 } else {
920 codec_ep = rep;
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948 dai_link->no_pcm = 1;
949 dai_link->be_hw_params_fixup = simple_util_be_hw_params_fixup;
950
951 ret = graph_parse_node(priv, GRAPH_DPCM, codec_ep, li, 0);
952 if (ret < 0)
953 return ret;
954 }
955
956 graph_parse_convert(ep, dai_props);
957 graph_parse_convert(rep, dai_props);
958
959 graph_link_init(priv, lnk, cpu_ep, codec_ep, li, is_cpu);
960
961 return graph_ret(priv, ret);
962}
963EXPORT_SYMBOL_GPL(audio_graph2_link_dpcm);
964
965int audio_graph2_link_c2c(struct simple_util_priv *priv,
966 struct device_node *lnk,
967 struct link_info *li)
968{
969 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link);
970 struct device_node *port0 = lnk;
971 struct device_node *ports __free(device_node) = port_to_ports(port0);
972 struct device_node *port1 __free(device_node) = of_graph_get_next_port(ports, port0);
973 u32 val = 0;
974 int ret = -EINVAL;
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001 of_property_read_u32(ports, "rate", &val);
1002 if (val) {
1003 struct device *dev = simple_priv_to_dev(priv);
1004 struct snd_soc_pcm_stream *c2c_conf;
1005
1006 c2c_conf = devm_kzalloc(dev, sizeof(*c2c_conf), GFP_KERNEL);
1007 if (!c2c_conf) {
1008
1009
1010
1011
1012 return graph_ret(priv, -ENOMEM);
1013 }
1014
1015 c2c_conf->formats = SNDRV_PCM_FMTBIT_S32_LE;
1016 c2c_conf->rates = SNDRV_PCM_RATE_8000_384000;
1017 c2c_conf->rate_min =
1018 c2c_conf->rate_max = val;
1019 c2c_conf->channels_min =
1020 c2c_conf->channels_max = 2;
1021
1022 dai_link->c2c_params = c2c_conf;
1023 dai_link->num_c2c_params = 1;
1024 }
1025
1026 struct device_node *ep0 __free(device_node) = of_graph_get_next_port_endpoint(port0, NULL);
1027 struct device_node *ep1 __free(device_node) = of_graph_get_next_port_endpoint(port1, NULL);
1028
1029 struct device_node *codec0_ep __free(device_node) = of_graph_get_remote_endpoint(ep0);
1030 struct device_node *codec1_ep __free(device_node) = of_graph_get_remote_endpoint(ep1);
1031
1032
1033
1034
1035
1036
1037 ret = graph_parse_node(priv, GRAPH_C2C, codec1_ep, li, 0);
1038 if (ret < 0)
1039 goto end;
1040
1041
1042
1043
1044 ret = graph_parse_node(priv, GRAPH_C2C, codec0_ep, li, 1);
1045 if (ret < 0)
1046 goto end;
1047
1048 graph_link_init(priv, lnk, codec0_ep, codec1_ep, li, 1);
1049end:
1050 return graph_ret(priv, ret);
1051}
1052EXPORT_SYMBOL_GPL(audio_graph2_link_c2c);
1053
1054static int graph_link(struct simple_util_priv *priv,
1055 struct graph2_custom_hooks *hooks,
1056 enum graph_type gtype,
1057 struct device_node *lnk,
1058 struct link_info *li)
1059{
1060 struct device *dev = simple_priv_to_dev(priv);
1061 GRAPH2_CUSTOM func = NULL;
1062 int ret = -EINVAL;
1063
1064 switch (gtype) {
1065 case GRAPH_NORMAL:
1066 if (hooks && hooks->custom_normal)
1067 func = hooks->custom_normal;
1068 else
1069 func = audio_graph2_link_normal;
1070 break;
1071 case GRAPH_DPCM:
1072 if (hooks && hooks->custom_dpcm)
1073 func = hooks->custom_dpcm;
1074 else
1075 func = audio_graph2_link_dpcm;
1076 break;
1077 case GRAPH_C2C:
1078 if (hooks && hooks->custom_c2c)
1079 func = hooks->custom_c2c;
1080 else
1081 func = audio_graph2_link_c2c;
1082 break;
1083 default:
1084 break;
1085 }
1086
1087 if (!func) {
1088 dev_err(dev, "non supported gtype (%d)\n", gtype);
1089 goto err;
1090 }
1091
1092 ret = func(priv, lnk, li);
1093 if (ret < 0)
1094 goto err;
1095
1096 li->link++;
1097err:
1098 return graph_ret(priv, ret);
1099}
1100
1101static int graph_counter(struct device_node *lnk)
1102{
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117 if (graph_lnk_is_multi(lnk)) {
1118 struct device_node *ports = port_to_ports(lnk);
1119
1120
1121
1122
1123
1124 return of_graph_get_port_count(ports) - 1;
1125 }
1126
1127
1128
1129 else
1130 return 1;
1131}
1132
1133static int graph_count_normal(struct simple_util_priv *priv,
1134 struct device_node *lnk,
1135 struct link_info *li)
1136{
1137 struct device_node *cpu_port = lnk;
1138 struct device_node *cpu_ep __free(device_node) = of_graph_get_next_port_endpoint(cpu_port, NULL);
1139 struct device_node *codec_port __free(device_node) = of_graph_get_remote_port(cpu_ep);
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151 li->num[li->link].cpus =
1152 li->num[li->link].platforms = graph_counter(cpu_port);
1153
1154 li->num[li->link].codecs = graph_counter(codec_port);
1155
1156 return 0;
1157}
1158
1159static int graph_count_dpcm(struct simple_util_priv *priv,
1160 struct device_node *lnk,
1161 struct link_info *li)
1162{
1163 struct device_node *ep __free(device_node) = of_graph_get_next_port_endpoint(lnk, NULL);
1164 struct device_node *rport __free(device_node) = of_graph_get_remote_port(ep);
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181 if (graph_util_is_ports0(lnk)) {
1182
1183
1184
1185
1186
1187 li->num[li->link].cpus = graph_counter(rport);
1188 li->num[li->link].platforms = graph_counter(rport);
1189 } else {
1190 li->num[li->link].codecs = graph_counter(rport);
1191 }
1192
1193 return 0;
1194}
1195
1196static int graph_count_c2c(struct simple_util_priv *priv,
1197 struct device_node *lnk,
1198 struct link_info *li)
1199{
1200 struct device_node *ports __free(device_node) = port_to_ports(lnk);
1201 struct device_node *port0 = of_node_get(lnk);
1202 struct device_node *port1 = of_node_get(of_graph_get_next_port(ports, of_node_get(port0)));
1203 struct device_node *ep0 __free(device_node) = of_graph_get_next_port_endpoint(port0, NULL);
1204 struct device_node *ep1 __free(device_node) = of_graph_get_next_port_endpoint(port1, NULL);
1205 struct device_node *codec0 __free(device_node) = of_graph_get_remote_port(ep0);
1206 struct device_node *codec1 __free(device_node) = of_graph_get_remote_port(ep1);
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221 li->num[li->link].cpus =
1222 li->num[li->link].platforms = graph_counter(codec0);
1223
1224 li->num[li->link].codecs = graph_counter(codec1);
1225
1226 return 0;
1227}
1228
1229static int graph_count(struct simple_util_priv *priv,
1230 struct graph2_custom_hooks *hooks,
1231 enum graph_type gtype,
1232 struct device_node *lnk,
1233 struct link_info *li)
1234{
1235 struct device *dev = simple_priv_to_dev(priv);
1236 GRAPH2_CUSTOM func = NULL;
1237 int ret = -EINVAL;
1238
1239 if (li->link >= SNDRV_MAX_LINKS) {
1240 dev_err(dev, "too many links\n");
1241 return ret;
1242 }
1243
1244 switch (gtype) {
1245 case GRAPH_NORMAL:
1246 func = graph_count_normal;
1247 break;
1248 case GRAPH_DPCM:
1249 func = graph_count_dpcm;
1250 break;
1251 case GRAPH_C2C:
1252 func = graph_count_c2c;
1253 break;
1254 default:
1255 break;
1256 }
1257
1258 if (!func) {
1259 dev_err(dev, "non supported gtype (%d)\n", gtype);
1260 goto err;
1261 }
1262
1263 ret = func(priv, lnk, li);
1264 if (ret < 0)
1265 goto err;
1266
1267 li->link++;
1268err:
1269 return graph_ret(priv, ret);
1270}
1271
1272static int graph_for_each_link(struct simple_util_priv *priv,
1273 struct graph2_custom_hooks *hooks,
1274 struct link_info *li,
1275 int (*func)(struct simple_util_priv *priv,
1276 struct graph2_custom_hooks *hooks,
1277 enum graph_type gtype,
1278 struct device_node *lnk,
1279 struct link_info *li))
1280{
1281 struct of_phandle_iterator it;
1282 struct device *dev = simple_priv_to_dev(priv);
1283 struct device_node *node = dev->of_node;
1284 struct device_node *lnk;
1285 enum graph_type gtype;
1286 int rc, ret = 0;
1287
1288
1289 of_for_each_phandle(&it, rc, node, "links", NULL, 0) {
1290 lnk = it.node;
1291
1292 gtype = graph_get_type(priv, lnk);
1293
1294 ret = func(priv, hooks, gtype, lnk, li);
1295 if (ret < 0)
1296 break;
1297 }
1298
1299 return graph_ret(priv, ret);
1300}
1301
1302int audio_graph2_parse_of(struct simple_util_priv *priv, struct device *dev,
1303 struct graph2_custom_hooks *hooks)
1304{
1305 struct snd_soc_card *card = simple_priv_to_card(priv);
1306 int ret;
1307
1308 struct link_info *li __free(kfree) = kzalloc(sizeof(*li), GFP_KERNEL);
1309 if (!li)
1310 return -ENOMEM;
1311
1312 card->probe = graph_util_card_probe;
1313 card->owner = THIS_MODULE;
1314 card->dev = dev;
1315
1316 if ((hooks) && (hooks)->hook_pre) {
1317 ret = (hooks)->hook_pre(priv);
1318 if (ret < 0)
1319 goto err;
1320 }
1321
1322 ret = graph_for_each_link(priv, hooks, li, graph_count);
1323 if (!li->link)
1324 ret = -EINVAL;
1325 if (ret < 0)
1326 goto err;
1327
1328 ret = simple_util_init_priv(priv, li);
1329 if (ret < 0)
1330 goto err;
1331
1332 priv->pa_gpio = devm_gpiod_get_optional(dev, "pa", GPIOD_OUT_LOW);
1333 if (IS_ERR(priv->pa_gpio)) {
1334 ret = PTR_ERR(priv->pa_gpio);
1335 dev_err(dev, "failed to get amplifier gpio: %d\n", ret);
1336 goto err;
1337 }
1338
1339 ret = simple_util_parse_widgets(card, NULL);
1340 if (ret < 0)
1341 goto err;
1342
1343 ret = simple_util_parse_routing(card, NULL);
1344 if (ret < 0)
1345 goto err;
1346
1347 memset(li, 0, sizeof(*li));
1348 ret = graph_for_each_link(priv, hooks, li, graph_link);
1349 if (ret < 0)
1350 goto err;
1351
1352 ret = simple_util_parse_card_name(priv, NULL);
1353 if (ret < 0)
1354 goto err;
1355
1356 snd_soc_card_set_drvdata(card, priv);
1357
1358 if ((hooks) && (hooks)->hook_post) {
1359 ret = (hooks)->hook_post(priv);
1360 if (ret < 0)
1361 goto err;
1362 }
1363
1364 simple_util_debug_info(priv);
1365
1366 ret = snd_soc_of_parse_aux_devs(card, "aux-devs");
1367 if (ret < 0)
1368 goto err;
1369
1370 ret = devm_snd_soc_register_card(dev, card);
1371err:
1372 if (ret < 0)
1373 dev_err_probe(dev, ret, "parse error\n");
1374
1375 return graph_ret(priv, ret);
1376}
1377EXPORT_SYMBOL_GPL(audio_graph2_parse_of);
1378
1379static int graph_probe(struct platform_device *pdev)
1380{
1381 struct simple_util_priv *priv;
1382 struct device *dev = &pdev->dev;
1383
1384
1385 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
1386 if (!priv)
1387 return -ENOMEM;
1388
1389 return audio_graph2_parse_of(priv, dev, NULL);
1390}
1391
1392static const struct of_device_id graph_of_match[] = {
1393 { .compatible = "audio-graph-card2", },
1394 {},
1395};
1396MODULE_DEVICE_TABLE(of, graph_of_match);
1397
1398static struct platform_driver graph_card = {
1399 .driver = {
1400 .name = "asoc-audio-graph-card2",
1401 .pm = &snd_soc_pm_ops,
1402 .of_match_table = graph_of_match,
1403 },
1404 .probe = graph_probe,
1405 .remove = simple_util_remove,
1406};
1407module_platform_driver(graph_card);
1408
1409MODULE_ALIAS("platform:asoc-audio-graph-card2");
1410MODULE_LICENSE("GPL v2");
1411MODULE_DESCRIPTION("ASoC Audio Graph Card2");
1412MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
1413