Lines Matching +full:audio +full:- +full:graph +full:- +full:card2
1 // SPDX-License-Identifier: GPL-2.0
3 // ASoC Audio Graph Card2 support
8 // based on ${LINUX}/sound/soc/generic/audio-graph-card.c
28 bitclock-master;
30 frame-master;
42 sample0: left_j, bitclock-master, frame-master
43 sample1: i2s, bitclock-master
51 Normal Audio-Graph
54 CPU <---> Codec
57 compatible = "audio-graph-card2";
63 bitclock-master;
64 frame-master;
65 cpu_ep: endpoint { remote-endpoint = <&codec_ep>; }; };
69 port { codec_ep: endpoint { remote-endpoint = <&cpu_ep>; }; };
73 Multi-CPU/Codec
79 +-+ (A) +-+
80 CPU1 --(y) | | <-(X)--(X)-> | | (y)-- Codec1
81 CPU2 --(y) | | | | (y)-- Codec2
82 +-+ +-+
85 compatible = "audio-graph-card2";
91 (X) (A) mcpu: port@0 { mcpu0_ep: endpoint { remote-endpoint = <&mcodec0_ep>; }; };
92 (y) port@1 { mcpu1_ep: endpoint { remote-endpoint = <&cpu1_ep>; }; };
93 (y) port@2 { mcpu2_ep: endpoint { remote-endpoint = <&cpu2_ep>; }; };
96 (X) port@0 { mcodec0_ep: endpoint { remote-endpoint = <&mcpu0_ep>; }; };
97 (y) port@1 { mcodec1_ep: endpoint { remote-endpoint = <&codec1_ep>; }; };
98 (y) port@2 { mcodec2_ep: endpoint { remote-endpoint = <&codec2_ep>; }; };
105 bitclock-master;
106 frame-master;
107 port@0 { cpu1_ep: endpoint { remote-endpoint = <&mcpu1_ep>; }; };
108 port@1 { cpu2_ep: endpoint { remote-endpoint = <&mcpu2_ep>; }; };
114 port@0 { codec1_ep: endpoint { remote-endpoint = <&mcodec1_ep>; }; };
115 port@1 { codec2_ep: endpoint { remote-endpoint = <&mcodec2_ep>; }; };
125 PCM0 <--> * fe0 be0 * <--> DAI0: Codec Headset
126 PCM1 <--> * fe1 be1 * <--> DAI1: Codec Speakers
127 PCM2 <--> * fe2 be2 * <--> DAI2: MODEM
128 PCM3 <--> * fe3 be3 * <--> DAI3: BT
129 * be4 * <--> DAI4: DMIC
130 * be5 * <--> DAI5: FM
134 compatible = "audio-graph-card2";
141 // indicate all Front-End, Back-End
146 // Front-End
148 fe0: port@0 { fe0_ep: endpoint { remote-endpoint = <&pcm0_ep>; }; };
149 fe1: port@1 { fe1_ep: endpoint { remote-endpoint = <&pcm1_ep>; }; };
152 // Back-End
154 be0: port@0 { be0_ep: endpoint { remote-endpoint = <&dai0_ep>; }; };
155 be1: port@1 { be1_ep: endpoint { remote-endpoint = <&dai1_ep>; }; };
163 bitclock-master;
164 frame-master;
165 port@0 { pcm0_ep: endpoint { remote-endpoint = <&fe0_ep>; }; };
166 port@1 { pcm1_ep: endpoint { remote-endpoint = <&fe1_ep>; }; };
173 port@0 { dai0_ep: endpoint { remote-endpoint = <&be0_ep>; }; };
174 port@1 { dai1_ep: endpoint { remote-endpoint = <&be1_ep>; }; };
183 +--+
184 | |<-- Codec0 <- IN
185 | |--> Codec1 -> OUT
186 +--+
189 compatible = "audio-graph-card2";
199 c2c: port@0 { c2cf_ep: endpoint { remote-endpoint = <&codec0_ep>; }; };
200 port@1 { c2cb_ep: endpoint { remote-endpoint = <&codec1_ep>; }; };
207 bitclock-master;
208 frame-master;
209 codec0_ep: endpoint { remote-endpoint = <&c2cf_ep>; }; };
210 port@1 { codec1_ep: endpoint { remote-endpoint = <&c2cb_ep>; }; };
290 str = "DPCM Front-End"; in graph_get_type()
292 str = "DPCM Back-End"; in graph_get_type()
367 if (ret != -ENOTSUPP) in graph_get_dai_id()
395 id = -1; in graph_get_dai_id()
405 return -ENODEV; in graph_get_dai_id()
423 /* Get dai->name */ in asoc_simple_parse_dai()
431 * Here, dlc->dai_name is pointer to CPU/Codec DAI name. in asoc_simple_parse_dai()
433 * dlc->dai_name is keeping unbinded CPU or Codec in asoc_simple_parse_dai()
436 * If user re-bind CPU or Codec driver again, ALSA SoC will try in asoc_simple_parse_dai()
447 ret = snd_soc_get_dai_name(&args, &dlc->dai_name); in asoc_simple_parse_dai()
453 dlc->of_node = node; in asoc_simple_parse_dai()
466 struct asoc_simple_data *adata = &props->adata; in graph_parse_convert()
484 of_property_read_u32(ports, "mclk-fs", &props->mclk_fs); in graph_parse_mclk_fs()
485 of_property_read_u32(port, "mclk-fs", &props->mclk_fs); in graph_parse_mclk_fs()
486 of_property_read_u32(ep, "mclk-fs", &props->mclk_fs); in graph_parse_mclk_fs()
499 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); in __graph_parse_node()
500 struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link); in __graph_parse_node()
534 if (!dai_link->name) { in __graph_parse_node()
540 if (dai_link->num_cpus > 1) in __graph_parse_node()
542 if (dai_link->num_codecs > 1) in __graph_parse_node()
549 asoc_simple_set_dailink_name(dev, dai_link, "%s%s-%s%s", in __graph_parse_node()
550 cpus->dai_name, cpu_multi, in __graph_parse_node()
551 codecs->dai_name, codec_multi); in __graph_parse_node()
556 cpus->of_node, cpus->dai_name, cpu_multi); in __graph_parse_node()
559 codecs->of_node, codecs->dai_name, codec_multi); in __graph_parse_node()
564 asoc_simple_set_dailink_name(dev, dai_link, "c2c.%s%s-%s%s", in __graph_parse_node()
565 cpus->dai_name, cpu_multi, in __graph_parse_node()
566 codecs->dai_name, codec_multi); in __graph_parse_node()
575 * if DPCM-BE case in __graph_parse_node()
584 snd_soc_of_parse_node_prefix(rports, cconf, codecs->of_node, "prefix"); in __graph_parse_node()
585 snd_soc_of_parse_node_prefix(rport, cconf, codecs->of_node, "prefix"); in __graph_parse_node()
663 * if (A) or (B) or (C) has bitclock-master / frame-master flag. in graph_parse_daifmt()
677 * This function is called by (C) -> (B) -> (A) order. in graph_parse_daifmt()
691 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); in graph_link_init()
733 dai_link->dai_fmt = daifmt | daiclk; in graph_link_init()
734 dai_link->init = asoc_simple_dai_init; in graph_link_init()
735 dai_link->ops = &graph_ops; in graph_link_init()
736 if (priv->ops) in graph_link_init()
737 dai_link->ops = priv->ops; in graph_link_init()
781 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); in audio_graph2_link_dpcm()
782 struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link); in audio_graph2_link_dpcm()
789 * // Front-End in audio_graph2_link_dpcm()
794 * // Back-End in audio_graph2_link_dpcm()
811 dai_link->dynamic = 1; in audio_graph2_link_dpcm()
812 dai_link->dpcm_merged_format = 1; in audio_graph2_link_dpcm()
820 * // Front-End in audio_graph2_link_dpcm()
824 * // Back-End in audio_graph2_link_dpcm()
844 dai_link->no_pcm = 1; in audio_graph2_link_dpcm()
845 dai_link->be_hw_params_fixup = asoc_simple_be_hw_params_fixup; in audio_graph2_link_dpcm()
870 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); in audio_graph2_link_c2c()
875 int ret = -EINVAL; in audio_graph2_link_c2c()
899 * Card2 can use original Codec2Codec settings if DT has. in audio_graph2_link_c2c()
915 c2c_conf->formats = SNDRV_PCM_FMTBIT_S32_LE; /* update ME */ in audio_graph2_link_c2c()
916 c2c_conf->rates = SNDRV_PCM_RATE_8000_384000; in audio_graph2_link_c2c()
917 c2c_conf->rate_min = in audio_graph2_link_c2c()
918 c2c_conf->rate_max = val; in audio_graph2_link_c2c()
919 c2c_conf->channels_min = in audio_graph2_link_c2c()
920 c2c_conf->channels_max = 2; /* update ME */ in audio_graph2_link_c2c()
922 dai_link->params = c2c_conf; in audio_graph2_link_c2c()
923 dai_link->num_params = 1; in audio_graph2_link_c2c()
971 int ret = -EINVAL; in graph_link()
975 if (hooks && hooks->custom_normal) in graph_link()
976 func = hooks->custom_normal; in graph_link()
981 if (hooks && hooks->custom_dpcm) in graph_link()
982 func = hooks->custom_dpcm; in graph_link()
987 if (hooks && hooks->custom_c2c) in graph_link()
988 func = hooks->custom_c2c; in graph_link()
1005 li->link++; in graph_link()
1027 return of_graph_get_endpoint_count(of_get_parent(lnk)) - 1; in graph_counter()
1048 li->num[li->link].cpus = in graph_count_normal()
1049 li->num[li->link].platforms = graph_counter(cpu_port); in graph_count_normal()
1050 li->num[li->link].codecs = graph_counter(codec_port); in graph_count_normal()
1067 * // Front-End in graph_count_dpcm()
1072 * // Back-End in graph_count_dpcm()
1081 li->num[li->link].cpus = graph_counter(rport); /* FE */ in graph_count_dpcm()
1082 li->num[li->link].platforms = graph_counter(rport); in graph_count_dpcm()
1084 li->num[li->link].codecs = graph_counter(rport); /* BE */ in graph_count_dpcm()
1115 li->num[li->link].cpus = in graph_count_c2c()
1116 li->num[li->link].platforms = graph_counter(codec0); in graph_count_c2c()
1117 li->num[li->link].codecs = graph_counter(codec1); in graph_count_c2c()
1137 int ret = -EINVAL; in graph_count()
1139 if (li->link >= SNDRV_MAX_LINKS) { in graph_count()
1167 li->link++; in graph_count()
1183 struct device_node *node = dev->of_node; in graph_for_each_link()
1211 return -ENOMEM; in audio_graph2_parse_of()
1213 card->probe = asoc_graph_card_probe; in audio_graph2_parse_of()
1214 card->owner = THIS_MODULE; in audio_graph2_parse_of()
1215 card->dev = dev; in audio_graph2_parse_of()
1217 if ((hooks) && (hooks)->hook_pre) { in audio_graph2_parse_of()
1218 ret = (hooks)->hook_pre(priv); in audio_graph2_parse_of()
1224 if (!li->link) in audio_graph2_parse_of()
1225 ret = -EINVAL; in audio_graph2_parse_of()
1233 priv->pa_gpio = devm_gpiod_get_optional(dev, "pa", GPIOD_OUT_LOW); in audio_graph2_parse_of()
1234 if (IS_ERR(priv->pa_gpio)) { in audio_graph2_parse_of()
1235 ret = PTR_ERR(priv->pa_gpio); in audio_graph2_parse_of()
1259 if ((hooks) && (hooks)->hook_post) { in audio_graph2_parse_of()
1260 ret = (hooks)->hook_post(priv); in audio_graph2_parse_of()
1275 dev_warn(dev, "Audio Graph Card2 is still under Experimental stage\n"); in audio_graph2_parse_of()
1284 struct device *dev = &pdev->dev; in graph_probe()
1289 return -ENOMEM; in graph_probe()
1295 { .compatible = "audio-graph-card2", },
1302 .name = "asoc-audio-graph-card2",
1311 MODULE_ALIAS("platform:asoc-audio-graph-card2");
1313 MODULE_DESCRIPTION("ASoC Audio Graph Card2");