Merge tag 'v6.6-p5' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
[platform/kernel/linux-rpi.git] / sound / soc / generic / audio-graph-card2.c
1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // ASoC Audio Graph Card2 support
4 //
5 // Copyright (C) 2020 Renesas Electronics Corp.
6 // Copyright (C) 2020 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
7 //
8 // based on ${LINUX}/sound/soc/generic/audio-graph-card.c
9 #include <linux/clk.h>
10 #include <linux/device.h>
11 #include <linux/gpio.h>
12 #include <linux/gpio/consumer.h>
13 #include <linux/module.h>
14 #include <linux/of.h>
15 #include <linux/of_device.h>
16 #include <linux/of_gpio.h>
17 #include <linux/of_graph.h>
18 #include <linux/platform_device.h>
19 #include <linux/string.h>
20 #include <sound/graph_card.h>
21
22 /************************************
23         daifmt
24  ************************************
25         ports {
26                 format = "left_j";
27                 port@0 {
28                         bitclock-master;
29                         sample0: endpoint@0 {
30                                 frame-master;
31                         };
32                         sample1: endpoint@1 {
33                                 format = "i2s";
34                         };
35                 };
36                 ...
37         };
38
39  You can set daifmt at ports/port/endpoint.
40  It uses *latest* format, and *share* master settings.
41  In above case,
42         sample0: left_j, bitclock-master, frame-master
43         sample1: i2s,    bitclock-master
44
45  If there was no settings, *Codec* will be
46  bitclock/frame provider as default.
47  see
48         graph_parse_daifmt().
49
50  "format" property is no longer needed on DT if both CPU/Codec drivers are
51  supporting snd_soc_dai_ops :: .auto_selectable_formats.
52  see
53         snd_soc_runtime_get_dai_fmt()
54
55         sample driver
56                 linux/sound/soc/sh/rcar/core.c
57                 linux/sound/soc/codecs/ak4613.c
58                 linux/sound/soc/codecs/pcm3168a.c
59                 linux/sound/soc/soc-utils.c
60                 linux/sound/soc/generic/test-component.c
61
62  ************************************
63         Normal Audio-Graph
64  ************************************
65
66  CPU <---> Codec
67
68  sound {
69         compatible = "audio-graph-card2";
70         links = <&cpu>;
71  };
72
73  CPU {
74         cpu: port {
75                 bitclock-master;
76                 frame-master;
77                 cpu_ep: endpoint { remote-endpoint = <&codec_ep>; }; };
78  };
79
80  Codec {
81         port {  codec_ep: endpoint { remote-endpoint = <&cpu_ep>; }; };
82  };
83
84  ************************************
85         Multi-CPU/Codec
86  ************************************
87
88 It has connection part (= X) and list part (= y).
89 links indicates connection part of CPU side (= A).
90
91             +-+   (A)        +-+
92  CPU1 --(y) | | <-(X)--(X)-> | | (y)-- Codec1
93  CPU2 --(y) | |              | | (y)-- Codec2
94             +-+              +-+
95
96         sound {
97                 compatible = "audio-graph-card2";
98
99 (A)             links = <&mcpu>;
100
101                 multi {
102                         ports@0 {
103 (X) (A)                 mcpu:   port@0 { mcpu0_ep: endpoint { remote-endpoint = <&mcodec0_ep>; }; };
104 (y)                             port@1 { mcpu1_ep: endpoint { remote-endpoint = <&cpu1_ep>; }; };
105 (y)                             port@2 { mcpu2_ep: endpoint { remote-endpoint = <&cpu2_ep>; }; };
106                         };
107                         ports@1 {
108 (X)                             port@0 { mcodec0_ep: endpoint { remote-endpoint = <&mcpu0_ep>; }; };
109 (y)                             port@1 { mcodec1_ep: endpoint { remote-endpoint = <&codec1_ep>; }; };
110 (y)                             port@2 { mcodec2_ep: endpoint { remote-endpoint = <&codec2_ep>; }; };
111                         };
112                 };
113         };
114
115  CPU {
116         ports {
117                 bitclock-master;
118                 frame-master;
119                 port@0 { cpu1_ep: endpoint { remote-endpoint = <&mcpu1_ep>; }; };
120                 port@1 { cpu2_ep: endpoint { remote-endpoint = <&mcpu2_ep>; }; };
121         };
122  };
123
124  Codec {
125         ports {
126                 port@0 { codec1_ep: endpoint { remote-endpoint = <&mcodec1_ep>; }; };
127                 port@1 { codec2_ep: endpoint { remote-endpoint = <&mcodec2_ep>; }; };
128         };
129  };
130
131  ************************************
132         DPCM
133  ************************************
134
135                 DSP
136            ************
137  PCM0 <--> * fe0  be0 * <--> DAI0: Codec Headset
138  PCM1 <--> * fe1  be1 * <--> DAI1: Codec Speakers
139  PCM2 <--> * fe2  be2 * <--> DAI2: MODEM
140  PCM3 <--> * fe3  be3 * <--> DAI3: BT
141            *      be4 * <--> DAI4: DMIC
142            *      be5 * <--> DAI5: FM
143            ************
144
145  sound {
146         compatible = "audio-graph-card2";
147
148         // indicate routing
149         routing = "xxx Playback", "xxx Playback",
150                   "xxx Playback", "xxx Playback",
151                   "xxx Playback", "xxx Playback";
152
153         // indicate all Front-End, Back-End
154         links = <&fe0, &fe1, ...,
155                  &be0, &be1, ...>;
156
157         dpcm {
158                 // Front-End
159                 ports@0 {
160                         fe0: port@0 { fe0_ep: endpoint { remote-endpoint = <&pcm0_ep>; }; };
161                         fe1: port@1 { fe1_ep: endpoint { remote-endpoint = <&pcm1_ep>; }; };
162                         ...
163                 };
164                 // Back-End
165                 ports@1 {
166                         be0: port@0 { be0_ep: endpoint { remote-endpoint = <&dai0_ep>; }; };
167                         be1: port@1 { be1_ep: endpoint { remote-endpoint = <&dai1_ep>; }; };
168                         ...
169                 };
170         };
171  };
172
173  CPU {
174         ports {
175                 bitclock-master;
176                 frame-master;
177                 port@0 { pcm0_ep: endpoint { remote-endpoint = <&fe0_ep>; }; };
178                 port@1 { pcm1_ep: endpoint { remote-endpoint = <&fe1_ep>; }; };
179                 ...
180         };
181  };
182
183  Codec {
184         ports {
185                 port@0 { dai0_ep: endpoint { remote-endpoint = <&be0_ep>; }; };
186                 port@1 { dai1_ep: endpoint { remote-endpoint = <&be1_ep>; }; };
187                 ...
188         };
189  };
190
191  ************************************
192         Codec to Codec
193  ************************************
194
195  +--+
196  |  |<-- Codec0 <- IN
197  |  |--> Codec1 -> OUT
198  +--+
199
200  sound {
201         compatible = "audio-graph-card2";
202
203         routing = "OUT" ,"DAI1 Playback",
204                   "DAI0 Capture", "IN";
205
206         links = <&c2c>;
207
208         codec2codec {
209                 ports {
210                         rate = <48000>;
211                 c2c:    port@0 { c2cf_ep: endpoint { remote-endpoint = <&codec0_ep>; }; };
212                         port@1 { c2cb_ep: endpoint { remote-endpoint = <&codec1_ep>; }; };
213         };
214  };
215
216  Codec {
217         ports {
218                 port@0 {
219                         bitclock-master;
220                         frame-master;
221                          codec0_ep: endpoint { remote-endpoint = <&c2cf_ep>; }; };
222                 port@1 { codec1_ep: endpoint { remote-endpoint = <&c2cb_ep>; }; };
223         };
224  };
225
226 */
227
228 enum graph_type {
229         GRAPH_NORMAL,
230         GRAPH_DPCM,
231         GRAPH_C2C,
232
233         GRAPH_MULTI,    /* don't use ! Use this only in __graph_get_type() */
234 };
235
236 #define GRAPH_NODENAME_MULTI    "multi"
237 #define GRAPH_NODENAME_DPCM     "dpcm"
238 #define GRAPH_NODENAME_C2C      "codec2codec"
239
240 #define port_to_endpoint(port) of_get_child_by_name(port, "endpoint")
241
242 static enum graph_type __graph_get_type(struct device_node *lnk)
243 {
244         struct device_node *np, *parent_np;
245         enum graph_type ret;
246
247         /*
248          * target {
249          *      ports {
250          * =>           lnk:    port@0 { ... };
251          *                      port@1 { ... };
252          *      };
253          * };
254          */
255         np = of_get_parent(lnk);
256         if (of_node_name_eq(np, "ports")) {
257                 parent_np = of_get_parent(np);
258                 of_node_put(np);
259                 np = parent_np;
260         }
261
262         if (of_node_name_eq(np, GRAPH_NODENAME_MULTI)) {
263                 ret = GRAPH_MULTI;
264                 goto out_put;
265         }
266
267         if (of_node_name_eq(np, GRAPH_NODENAME_DPCM)) {
268                 ret = GRAPH_DPCM;
269                 goto out_put;
270         }
271
272         if (of_node_name_eq(np, GRAPH_NODENAME_C2C)) {
273                 ret = GRAPH_C2C;
274                 goto out_put;
275         }
276
277         ret = GRAPH_NORMAL;
278
279 out_put:
280         of_node_put(np);
281         return ret;
282
283 }
284
285 static enum graph_type graph_get_type(struct asoc_simple_priv *priv,
286                                       struct device_node *lnk)
287 {
288         enum graph_type type = __graph_get_type(lnk);
289
290         /* GRAPH_MULTI here means GRAPH_NORMAL */
291         if (type == GRAPH_MULTI)
292                 type = GRAPH_NORMAL;
293
294 #ifdef DEBUG
295         {
296                 struct device *dev = simple_priv_to_dev(priv);
297                 const char *str = "Normal";
298
299                 switch (type) {
300                 case GRAPH_DPCM:
301                         if (asoc_graph_is_ports0(lnk))
302                                 str = "DPCM Front-End";
303                         else
304                                 str = "DPCM Back-End";
305                         break;
306                 case GRAPH_C2C:
307                         str = "Codec2Codec";
308                         break;
309                 default:
310                         break;
311                 }
312
313                 dev_dbg(dev, "%pOF (%s)", lnk, str);
314         }
315 #endif
316         return type;
317 }
318
319 static int graph_lnk_is_multi(struct device_node *lnk)
320 {
321         return __graph_get_type(lnk) == GRAPH_MULTI;
322 }
323
324 static struct device_node *graph_get_next_multi_ep(struct device_node **port)
325 {
326         struct device_node *ports = of_get_parent(*port);
327         struct device_node *ep = NULL;
328         struct device_node *rep = NULL;
329
330         /*
331          * multi {
332          *      ports {
333          * =>   lnk:    port@0 { ... };
334          *              port@1 { ep { ... = rep0 } };
335          *              port@2 { ep { ... = rep1 } };
336          *              ...
337          *      };
338          * };
339          *
340          * xxx {
341          *      port@0 { rep0 };
342          *      port@1 { rep1 };
343          * };
344          */
345         do {
346                 *port = of_get_next_child(ports, *port);
347                 if (!*port)
348                         break;
349         } while (!of_node_name_eq(*port, "port"));
350
351         if (*port) {
352                 ep  = port_to_endpoint(*port);
353                 rep = of_graph_get_remote_endpoint(ep);
354         }
355
356         of_node_put(ep);
357         of_node_put(ports);
358
359         return rep;
360 }
361
362 static const struct snd_soc_ops graph_ops = {
363         .startup        = asoc_simple_startup,
364         .shutdown       = asoc_simple_shutdown,
365         .hw_params      = asoc_simple_hw_params,
366 };
367
368 static void graph_parse_convert(struct device_node *ep,
369                                 struct simple_dai_props *props)
370 {
371         struct device_node *port = of_get_parent(ep);
372         struct device_node *ports = of_get_parent(port);
373         struct asoc_simple_data *adata = &props->adata;
374
375         if (of_node_name_eq(ports, "ports"))
376                 asoc_simple_parse_convert(ports, NULL, adata);
377         asoc_simple_parse_convert(port, NULL, adata);
378         asoc_simple_parse_convert(ep,   NULL, adata);
379
380         of_node_put(port);
381         of_node_put(ports);
382 }
383
384 static void graph_parse_mclk_fs(struct device_node *ep,
385                                 struct simple_dai_props *props)
386 {
387         struct device_node *port        = of_get_parent(ep);
388         struct device_node *ports       = of_get_parent(port);
389
390         if (of_node_name_eq(ports, "ports"))
391                 of_property_read_u32(ports, "mclk-fs", &props->mclk_fs);
392         of_property_read_u32(port,      "mclk-fs", &props->mclk_fs);
393         of_property_read_u32(ep,        "mclk-fs", &props->mclk_fs);
394
395         of_node_put(port);
396         of_node_put(ports);
397 }
398
399 static int __graph_parse_node(struct asoc_simple_priv *priv,
400                               enum graph_type gtype,
401                               struct device_node *ep,
402                               struct link_info *li,
403                               int is_cpu, int idx)
404 {
405         struct device *dev = simple_priv_to_dev(priv);
406         struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link);
407         struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link);
408         struct snd_soc_dai_link_component *dlc;
409         struct asoc_simple_dai *dai;
410         int ret, is_single_links = 0;
411
412         if (is_cpu) {
413                 dlc = asoc_link_to_cpu(dai_link, idx);
414                 dai = simple_props_to_dai_cpu(dai_props, idx);
415         } else {
416                 dlc = asoc_link_to_codec(dai_link, idx);
417                 dai = simple_props_to_dai_codec(dai_props, idx);
418         }
419
420         graph_parse_mclk_fs(ep, dai_props);
421
422         ret = asoc_graph_parse_dai(dev, ep, dlc, &is_single_links);
423         if (ret < 0)
424                 return ret;
425
426         ret = asoc_simple_parse_tdm(ep, dai);
427         if (ret < 0)
428                 return ret;
429
430         ret = asoc_simple_parse_tdm_width_map(dev, ep, dai);
431         if (ret < 0)
432                 return ret;
433
434         ret = asoc_simple_parse_clk(dev, ep, dai, dlc);
435         if (ret < 0)
436                 return ret;
437
438         /*
439          * set DAI Name
440          */
441         if (!dai_link->name) {
442                 struct snd_soc_dai_link_component *cpus = dlc;
443                 struct snd_soc_dai_link_component *codecs = asoc_link_to_codec(dai_link, idx);
444                 char *cpu_multi   = "";
445                 char *codec_multi = "";
446
447                 if (dai_link->num_cpus > 1)
448                         cpu_multi = "_multi";
449                 if (dai_link->num_codecs > 1)
450                         codec_multi = "_multi";
451
452                 switch (gtype) {
453                 case GRAPH_NORMAL:
454                         /* run is_cpu only. see audio_graph2_link_normal() */
455                         if (is_cpu)
456                                 asoc_simple_set_dailink_name(dev, dai_link, "%s%s-%s%s",
457                                                                cpus->dai_name,   cpu_multi,
458                                                              codecs->dai_name, codec_multi);
459                         break;
460                 case GRAPH_DPCM:
461                         if (is_cpu)
462                                 asoc_simple_set_dailink_name(dev, dai_link, "fe.%pOFP.%s%s",
463                                                 cpus->of_node, cpus->dai_name, cpu_multi);
464                         else
465                                 asoc_simple_set_dailink_name(dev, dai_link, "be.%pOFP.%s%s",
466                                                 codecs->of_node, codecs->dai_name, codec_multi);
467                         break;
468                 case GRAPH_C2C:
469                         /* run is_cpu only. see audio_graph2_link_c2c() */
470                         if (is_cpu)
471                                 asoc_simple_set_dailink_name(dev, dai_link, "c2c.%s%s-%s%s",
472                                                              cpus->dai_name,   cpu_multi,
473                                                              codecs->dai_name, codec_multi);
474                         break;
475                 default:
476                         break;
477                 }
478         }
479
480         /*
481          * Check "prefix" from top node
482          * if DPCM-BE case
483          */
484         if (!is_cpu && gtype == GRAPH_DPCM) {
485                 struct snd_soc_dai_link_component *codecs = asoc_link_to_codec(dai_link, idx);
486                 struct snd_soc_codec_conf *cconf = simple_props_to_codec_conf(dai_props, idx);
487                 struct device_node *rport  = of_get_parent(ep);
488                 struct device_node *rports = of_get_parent(rport);
489
490                 if (of_node_name_eq(rports, "ports"))
491                         snd_soc_of_parse_node_prefix(rports, cconf, codecs->of_node, "prefix");
492                 snd_soc_of_parse_node_prefix(rport,  cconf, codecs->of_node, "prefix");
493
494                 of_node_put(rport);
495                 of_node_put(rports);
496         }
497
498         if (is_cpu) {
499                 struct snd_soc_dai_link_component *cpus = dlc;
500                 struct snd_soc_dai_link_component *platforms = asoc_link_to_platform(dai_link, idx);
501
502                 asoc_simple_canonicalize_cpu(cpus, is_single_links);
503                 asoc_simple_canonicalize_platform(platforms, cpus);
504         }
505
506         return 0;
507 }
508
509 static int graph_parse_node(struct asoc_simple_priv *priv,
510                             enum graph_type gtype,
511                             struct device_node *port,
512                             struct link_info *li, int is_cpu)
513 {
514         struct device_node *ep;
515         int ret = 0;
516
517         if (graph_lnk_is_multi(port)) {
518                 int idx;
519
520                 of_node_get(port);
521
522                 for (idx = 0;; idx++) {
523                         ep = graph_get_next_multi_ep(&port);
524                         if (!ep)
525                                 break;
526
527                         ret = __graph_parse_node(priv, gtype, ep,
528                                                  li, is_cpu, idx);
529                         of_node_put(ep);
530                         if (ret < 0)
531                                 break;
532                 }
533         } else {
534                 /* Single CPU / Codec */
535                 ep = port_to_endpoint(port);
536                 ret = __graph_parse_node(priv, gtype, ep, li, is_cpu, 0);
537                 of_node_put(ep);
538         }
539
540         return ret;
541 }
542
543 static void graph_parse_daifmt(struct device_node *node,
544                                unsigned int *daifmt, unsigned int *bit_frame)
545 {
546         unsigned int fmt;
547
548         /*
549          * see also above "daifmt" explanation
550          * and samples.
551          */
552
553         /*
554          *      ports {
555          * (A)
556          *              port {
557          * (B)
558          *                      endpoint {
559          * (C)
560          *                      };
561          *              };
562          *      };
563          * };
564          */
565
566         /*
567          * clock_provider:
568          *
569          * It can be judged it is provider
570          * if (A) or (B) or (C) has bitclock-master / frame-master flag.
571          *
572          * use "or"
573          */
574         *bit_frame |= snd_soc_daifmt_parse_clock_provider_as_bitmap(node, NULL);
575
576 #define update_daifmt(name)                                     \
577         if (!(*daifmt & SND_SOC_DAIFMT_##name##_MASK) &&        \
578                  (fmt & SND_SOC_DAIFMT_##name##_MASK))          \
579                 *daifmt |= fmt & SND_SOC_DAIFMT_##name##_MASK
580
581         /*
582          * format
583          *
584          * This function is called by (C) -> (B) -> (A) order.
585          * Set if applicable part was not yet set.
586          */
587         fmt = snd_soc_daifmt_parse_format(node, NULL);
588         update_daifmt(FORMAT);
589         update_daifmt(CLOCK);
590         update_daifmt(INV);
591 }
592
593 static void graph_link_init(struct asoc_simple_priv *priv,
594                             struct device_node *port,
595                             struct link_info *li,
596                             int is_cpu_node)
597 {
598         struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link);
599         struct device_node *ep;
600         struct device_node *ports;
601         unsigned int daifmt = 0, daiclk = 0;
602         unsigned int bit_frame = 0;
603
604         if (graph_lnk_is_multi(port)) {
605                 of_node_get(port);
606                 ep = graph_get_next_multi_ep(&port);
607                 port = of_get_parent(ep);
608         } else {
609                 ep = port_to_endpoint(port);
610         }
611
612         ports = of_get_parent(port);
613
614         /*
615          *      ports {
616          * (A)
617          *              port {
618          * (B)
619          *                      endpoint {
620          * (C)
621          *                      };
622          *              };
623          *      };
624          * };
625          */
626         graph_parse_daifmt(ep,    &daifmt, &bit_frame);         /* (C) */
627         graph_parse_daifmt(port,  &daifmt, &bit_frame);         /* (B) */
628         if (of_node_name_eq(ports, "ports"))
629                 graph_parse_daifmt(ports, &daifmt, &bit_frame); /* (A) */
630
631         /*
632          * convert bit_frame
633          * We need to flip clock_provider if it was CPU node,
634          * because it is Codec base.
635          */
636         daiclk = snd_soc_daifmt_clock_provider_from_bitmap(bit_frame);
637         if (is_cpu_node)
638                 daiclk = snd_soc_daifmt_clock_provider_flipped(daiclk);
639
640         dai_link->dai_fmt       = daifmt | daiclk;
641         dai_link->init          = asoc_simple_dai_init;
642         dai_link->ops           = &graph_ops;
643         if (priv->ops)
644                 dai_link->ops   = priv->ops;
645 }
646
647 int audio_graph2_link_normal(struct asoc_simple_priv *priv,
648                              struct device_node *lnk,
649                              struct link_info *li)
650 {
651         struct device_node *cpu_port = lnk;
652         struct device_node *cpu_ep = port_to_endpoint(cpu_port);
653         struct device_node *codec_port = of_graph_get_remote_port(cpu_ep);
654         int ret;
655
656         /*
657          * call Codec first.
658          * see
659          *      __graph_parse_node() :: DAI Naming
660          */
661         ret = graph_parse_node(priv, GRAPH_NORMAL, codec_port, li, 0);
662         if (ret < 0)
663                 goto err;
664
665         /*
666          * call CPU, and set DAI Name
667          */
668         ret = graph_parse_node(priv, GRAPH_NORMAL, cpu_port, li, 1);
669         if (ret < 0)
670                 goto err;
671
672         graph_link_init(priv, cpu_port, li, 1);
673 err:
674         of_node_put(codec_port);
675         of_node_put(cpu_ep);
676
677         return ret;
678 }
679 EXPORT_SYMBOL_GPL(audio_graph2_link_normal);
680
681 int audio_graph2_link_dpcm(struct asoc_simple_priv *priv,
682                            struct device_node *lnk,
683                            struct link_info *li)
684 {
685         struct device_node *ep = port_to_endpoint(lnk);
686         struct device_node *rep = of_graph_get_remote_endpoint(ep);
687         struct device_node *rport = of_graph_get_remote_port(ep);
688         struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link);
689         struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link);
690         int is_cpu = asoc_graph_is_ports0(lnk);
691         int ret;
692
693         if (is_cpu) {
694                 /*
695                  * dpcm {
696                  *      // Front-End
697                  *      ports@0 {
698                  * =>           lnk: port@0 { ep: { ... = rep }; };
699                  *               ...
700                  *      };
701                  *      // Back-End
702                  *      ports@0 {
703                  *               ...
704                  *      };
705                  * };
706                  *
707                  * CPU {
708                  *      rports: ports {
709                  *              rport: port@0 { rep: { ... = ep } };
710                  *      }
711                  * }
712                  */
713                 /*
714                  * setup CPU here, Codec is already set as dummy.
715                  * see
716                  *      asoc_simple_init_priv()
717                  */
718                 dai_link->dynamic               = 1;
719                 dai_link->dpcm_merged_format    = 1;
720
721                 ret = graph_parse_node(priv, GRAPH_DPCM, rport, li, 1);
722                 if (ret)
723                         goto err;
724         } else {
725                 /*
726                  * dpcm {
727                  *      // Front-End
728                  *      ports@0 {
729                  *               ...
730                  *      };
731                  *      // Back-End
732                  *      ports@0 {
733                  * =>           lnk: port@0 { ep: { ... = rep; }; };
734                  *               ...
735                  *      };
736                  * };
737                  *
738                  * Codec {
739                  *      rports: ports {
740                  *              rport: port@0 { rep: { ... = ep; }; };
741                  *      }
742                  * }
743                  */
744                 /*
745                  * setup Codec here, CPU is already set as dummy.
746                  * see
747                  *      asoc_simple_init_priv()
748                  */
749
750                 /* BE settings */
751                 dai_link->no_pcm                = 1;
752                 dai_link->be_hw_params_fixup    = asoc_simple_be_hw_params_fixup;
753
754                 ret = graph_parse_node(priv, GRAPH_DPCM, rport, li, 0);
755                 if (ret < 0)
756                         goto err;
757         }
758
759         graph_parse_convert(ep,  dai_props); /* at node of <dpcm> */
760         graph_parse_convert(rep, dai_props); /* at node of <CPU/Codec> */
761
762         snd_soc_dai_link_set_capabilities(dai_link);
763
764         graph_link_init(priv, rport, li, is_cpu);
765 err:
766         of_node_put(ep);
767         of_node_put(rep);
768         of_node_put(rport);
769
770         return ret;
771 }
772 EXPORT_SYMBOL_GPL(audio_graph2_link_dpcm);
773
774 int audio_graph2_link_c2c(struct asoc_simple_priv *priv,
775                           struct device_node *lnk,
776                           struct link_info *li)
777 {
778         struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link);
779         struct device_node *port0, *port1, *ports;
780         struct device_node *codec0_port, *codec1_port;
781         struct device_node *ep0, *ep1;
782         u32 val = 0;
783         int ret = -EINVAL;
784
785         /*
786          * codec2codec {
787          *      ports {
788          *              rate = <48000>;
789          * =>   lnk:    port@0 { c2c0_ep: { ... = codec0_ep; }; };
790          *              port@1 { c2c1_ep: { ... = codec1_ep; }; };
791          *      };
792          * };
793          *
794          * Codec {
795          *      ports {
796          *              port@0 { codec0_ep: ... }; };
797          *              port@1 { codec1_ep: ... }; };
798          *      };
799          * };
800          */
801         of_node_get(lnk);
802         port0 = lnk;
803         ports = of_get_parent(port0);
804         port1 = of_get_next_child(ports, lnk);
805
806         /*
807          * Card2 can use original Codec2Codec settings if DT has.
808          * It will use default settings if no settings on DT.
809          * see
810          *      asoc_simple_init_for_codec2codec()
811          *
812          * Add more settings here if needed
813          */
814         of_property_read_u32(ports, "rate", &val);
815         if (val) {
816                 struct device *dev = simple_priv_to_dev(priv);
817                 struct snd_soc_pcm_stream *c2c_conf;
818
819                 c2c_conf = devm_kzalloc(dev, sizeof(*c2c_conf), GFP_KERNEL);
820                 if (!c2c_conf)
821                         goto err1;
822
823                 c2c_conf->formats       = SNDRV_PCM_FMTBIT_S32_LE; /* update ME */
824                 c2c_conf->rates         = SNDRV_PCM_RATE_8000_384000;
825                 c2c_conf->rate_min      =
826                 c2c_conf->rate_max      = val;
827                 c2c_conf->channels_min  =
828                 c2c_conf->channels_max  = 2; /* update ME */
829
830                 dai_link->c2c_params            = c2c_conf;
831                 dai_link->num_c2c_params        = 1;
832         }
833
834         ep0 = port_to_endpoint(port0);
835         ep1 = port_to_endpoint(port1);
836
837         codec0_port = of_graph_get_remote_port(ep0);
838         codec1_port = of_graph_get_remote_port(ep1);
839
840         /*
841          * call Codec first.
842          * see
843          *      __graph_parse_node() :: DAI Naming
844          */
845         ret = graph_parse_node(priv, GRAPH_C2C, codec1_port, li, 0);
846         if (ret < 0)
847                 goto err2;
848
849         /*
850          * call CPU, and set DAI Name
851          */
852         ret = graph_parse_node(priv, GRAPH_C2C, codec0_port, li, 1);
853         if (ret < 0)
854                 goto err2;
855
856         graph_link_init(priv, codec0_port, li, 1);
857 err2:
858         of_node_put(ep0);
859         of_node_put(ep1);
860         of_node_put(codec0_port);
861         of_node_put(codec1_port);
862 err1:
863         of_node_put(ports);
864         of_node_put(port0);
865         of_node_put(port1);
866
867         return ret;
868 }
869 EXPORT_SYMBOL_GPL(audio_graph2_link_c2c);
870
871 static int graph_link(struct asoc_simple_priv *priv,
872                       struct graph2_custom_hooks *hooks,
873                       enum graph_type gtype,
874                       struct device_node *lnk,
875                       struct link_info *li)
876 {
877         struct device *dev = simple_priv_to_dev(priv);
878         GRAPH2_CUSTOM func = NULL;
879         int ret = -EINVAL;
880
881         switch (gtype) {
882         case GRAPH_NORMAL:
883                 if (hooks && hooks->custom_normal)
884                         func = hooks->custom_normal;
885                 else
886                         func = audio_graph2_link_normal;
887                 break;
888         case GRAPH_DPCM:
889                 if (hooks && hooks->custom_dpcm)
890                         func = hooks->custom_dpcm;
891                 else
892                         func = audio_graph2_link_dpcm;
893                 break;
894         case GRAPH_C2C:
895                 if (hooks && hooks->custom_c2c)
896                         func = hooks->custom_c2c;
897                 else
898                         func = audio_graph2_link_c2c;
899                 break;
900         default:
901                 break;
902         }
903
904         if (!func) {
905                 dev_err(dev, "non supported gtype (%d)\n", gtype);
906                 goto err;
907         }
908
909         ret = func(priv, lnk, li);
910         if (ret < 0)
911                 goto err;
912
913         li->link++;
914 err:
915         return ret;
916 }
917
918 static int graph_counter(struct device_node *lnk)
919 {
920         /*
921          * Multi CPU / Codec
922          *
923          * multi {
924          *      ports {
925          * =>           lnk:    port@0 { ... };
926          *                      port@1 { ... };
927          *                      port@2 { ... };
928          *                      ...
929          *      };
930          * };
931          *
932          * ignore first lnk part
933          */
934         if (graph_lnk_is_multi(lnk))
935                 return of_graph_get_endpoint_count(of_get_parent(lnk)) - 1;
936         /*
937          * Single CPU / Codec
938          */
939         else
940                 return 1;
941 }
942
943 static int graph_count_normal(struct asoc_simple_priv *priv,
944                               struct device_node *lnk,
945                               struct link_info *li)
946 {
947         struct device_node *cpu_port = lnk;
948         struct device_node *cpu_ep = port_to_endpoint(cpu_port);
949         struct device_node *codec_port = of_graph_get_remote_port(cpu_ep);
950
951         /*
952          *      CPU {
953          * =>           lnk: port { endpoint { .. }; };
954          *      };
955          */
956         /*
957          * DON'T REMOVE platforms
958          * see
959          *      simple-card.c :: simple_count_noml()
960          */
961         li->num[li->link].cpus          =
962         li->num[li->link].platforms     = graph_counter(cpu_port);
963
964         li->num[li->link].codecs        = graph_counter(codec_port);
965
966         of_node_put(cpu_ep);
967         of_node_put(codec_port);
968
969         return 0;
970 }
971
972 static int graph_count_dpcm(struct asoc_simple_priv *priv,
973                             struct device_node *lnk,
974                             struct link_info *li)
975 {
976         struct device_node *ep = port_to_endpoint(lnk);
977         struct device_node *rport = of_graph_get_remote_port(ep);
978
979         /*
980          * dpcm {
981          *      // Front-End
982          *      ports@0 {
983          * =>           lnk: port@0 { endpoint { ... }; };
984          *               ...
985          *      };
986          *      // Back-End
987          *      ports@1 {
988          * =>           lnk: port@0 { endpoint { ... }; };
989          *               ...
990          *      };
991          * };
992          */
993
994         if (asoc_graph_is_ports0(lnk)) {
995                 /*
996                  * DON'T REMOVE platforms
997                  * see
998                  *      simple-card.c :: simple_count_noml()
999                  */
1000                 li->num[li->link].cpus          = graph_counter(rport); /* FE */
1001                 li->num[li->link].platforms     = graph_counter(rport);
1002         } else {
1003                 li->num[li->link].codecs        = graph_counter(rport); /* BE */
1004         }
1005
1006         of_node_put(ep);
1007         of_node_put(rport);
1008
1009         return 0;
1010 }
1011
1012 static int graph_count_c2c(struct asoc_simple_priv *priv,
1013                            struct device_node *lnk,
1014                            struct link_info *li)
1015 {
1016         struct device_node *ports = of_get_parent(lnk);
1017         struct device_node *port0 = lnk;
1018         struct device_node *port1 = of_get_next_child(ports, lnk);
1019         struct device_node *ep0 = port_to_endpoint(port0);
1020         struct device_node *ep1 = port_to_endpoint(port1);
1021         struct device_node *codec0 = of_graph_get_remote_port(ep0);
1022         struct device_node *codec1 = of_graph_get_remote_port(ep1);
1023
1024         of_node_get(lnk);
1025
1026         /*
1027          * codec2codec {
1028          *      ports {
1029          * =>   lnk:    port@0 { endpoint { ... }; };
1030          *              port@1 { endpoint { ... }; };
1031          *      };
1032          * };
1033          */
1034         /*
1035          * DON'T REMOVE platforms
1036          * see
1037          *      simple-card.c :: simple_count_noml()
1038          */
1039         li->num[li->link].cpus          =
1040         li->num[li->link].platforms     = graph_counter(codec0);
1041
1042         li->num[li->link].codecs        = graph_counter(codec1);
1043
1044         of_node_put(ports);
1045         of_node_put(port1);
1046         of_node_put(ep0);
1047         of_node_put(ep1);
1048         of_node_put(codec0);
1049         of_node_put(codec1);
1050
1051         return 0;
1052 }
1053
1054 static int graph_count(struct asoc_simple_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         if (li->link >= SNDRV_MAX_LINKS) {
1065                 dev_err(dev, "too many links\n");
1066                 return ret;
1067         }
1068
1069         switch (gtype) {
1070         case GRAPH_NORMAL:
1071                 func = graph_count_normal;
1072                 break;
1073         case GRAPH_DPCM:
1074                 func = graph_count_dpcm;
1075                 break;
1076         case GRAPH_C2C:
1077                 func = graph_count_c2c;
1078                 break;
1079         default:
1080                 break;
1081         }
1082
1083         if (!func) {
1084                 dev_err(dev, "non supported gtype (%d)\n", gtype);
1085                 goto err;
1086         }
1087
1088         ret = func(priv, lnk, li);
1089         if (ret < 0)
1090                 goto err;
1091
1092         li->link++;
1093 err:
1094         return ret;
1095 }
1096
1097 static int graph_for_each_link(struct asoc_simple_priv *priv,
1098                                struct graph2_custom_hooks *hooks,
1099                                struct link_info *li,
1100                                int (*func)(struct asoc_simple_priv *priv,
1101                                            struct graph2_custom_hooks *hooks,
1102                                            enum graph_type gtype,
1103                                            struct device_node *lnk,
1104                                            struct link_info *li))
1105 {
1106         struct of_phandle_iterator it;
1107         struct device *dev = simple_priv_to_dev(priv);
1108         struct device_node *node = dev->of_node;
1109         struct device_node *lnk;
1110         enum graph_type gtype;
1111         int rc, ret;
1112
1113         /* loop for all listed CPU port */
1114         of_for_each_phandle(&it, rc, node, "links", NULL, 0) {
1115                 lnk = it.node;
1116
1117                 gtype = graph_get_type(priv, lnk);
1118
1119                 ret = func(priv, hooks, gtype, lnk, li);
1120                 if (ret < 0)
1121                         return ret;
1122         }
1123
1124         return 0;
1125 }
1126
1127 int audio_graph2_parse_of(struct asoc_simple_priv *priv, struct device *dev,
1128                           struct graph2_custom_hooks *hooks)
1129 {
1130         struct snd_soc_card *card = simple_priv_to_card(priv);
1131         struct link_info *li;
1132         int ret;
1133
1134         li = devm_kzalloc(dev, sizeof(*li), GFP_KERNEL);
1135         if (!li)
1136                 return -ENOMEM;
1137
1138         card->probe     = asoc_graph_card_probe;
1139         card->owner     = THIS_MODULE;
1140         card->dev       = dev;
1141
1142         if ((hooks) && (hooks)->hook_pre) {
1143                 ret = (hooks)->hook_pre(priv);
1144                 if (ret < 0)
1145                         goto err;
1146         }
1147
1148         ret = graph_for_each_link(priv, hooks, li, graph_count);
1149         if (!li->link)
1150                 ret = -EINVAL;
1151         if (ret < 0)
1152                 goto err;
1153
1154         ret = asoc_simple_init_priv(priv, li);
1155         if (ret < 0)
1156                 goto err;
1157
1158         priv->pa_gpio = devm_gpiod_get_optional(dev, "pa", GPIOD_OUT_LOW);
1159         if (IS_ERR(priv->pa_gpio)) {
1160                 ret = PTR_ERR(priv->pa_gpio);
1161                 dev_err(dev, "failed to get amplifier gpio: %d\n", ret);
1162                 goto err;
1163         }
1164
1165         ret = asoc_simple_parse_widgets(card, NULL);
1166         if (ret < 0)
1167                 goto err;
1168
1169         ret = asoc_simple_parse_routing(card, NULL);
1170         if (ret < 0)
1171                 goto err;
1172
1173         memset(li, 0, sizeof(*li));
1174         ret = graph_for_each_link(priv, hooks, li, graph_link);
1175         if (ret < 0)
1176                 goto err;
1177
1178         ret = asoc_simple_parse_card_name(card, NULL);
1179         if (ret < 0)
1180                 goto err;
1181
1182         snd_soc_card_set_drvdata(card, priv);
1183
1184         if ((hooks) && (hooks)->hook_post) {
1185                 ret = (hooks)->hook_post(priv);
1186                 if (ret < 0)
1187                         goto err;
1188         }
1189
1190         asoc_simple_debug_info(priv);
1191
1192         ret = devm_snd_soc_register_card(dev, card);
1193 err:
1194         devm_kfree(dev, li);
1195
1196         if (ret < 0)
1197                 dev_err_probe(dev, ret, "parse error\n");
1198
1199         return ret;
1200 }
1201 EXPORT_SYMBOL_GPL(audio_graph2_parse_of);
1202
1203 static int graph_probe(struct platform_device *pdev)
1204 {
1205         struct asoc_simple_priv *priv;
1206         struct device *dev = &pdev->dev;
1207
1208         /* Allocate the private data and the DAI link array */
1209         priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
1210         if (!priv)
1211                 return -ENOMEM;
1212
1213         return audio_graph2_parse_of(priv, dev, NULL);
1214 }
1215
1216 static const struct of_device_id graph_of_match[] = {
1217         { .compatible = "audio-graph-card2", },
1218         {},
1219 };
1220 MODULE_DEVICE_TABLE(of, graph_of_match);
1221
1222 static struct platform_driver graph_card = {
1223         .driver = {
1224                 .name = "asoc-audio-graph-card2",
1225                 .pm = &snd_soc_pm_ops,
1226                 .of_match_table = graph_of_match,
1227         },
1228         .probe  = graph_probe,
1229         .remove = asoc_simple_remove,
1230 };
1231 module_platform_driver(graph_card);
1232
1233 MODULE_ALIAS("platform:asoc-audio-graph-card2");
1234 MODULE_LICENSE("GPL v2");
1235 MODULE_DESCRIPTION("ASoC Audio Graph Card2");
1236 MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");