Lines Matching +full:audio +full:- +full:ports

1 // SPDX-License-Identifier: GPL-2.0
3 // ASoC Audio Graph Card2 support
8 // based on ${LINUX}/sound/soc/generic/audio-graph-card.c
22 ports {
25 bitclock-master;
27 frame-master;
36 You can set daifmt at ports/port/endpoint.
39 sample0: left_j, bitclock-master, frame-master
40 sample1: i2s, bitclock-master
56 linux/sound/soc/soc-utils.c
57 linux/sound/soc/generic/test-component.c
60 Normal Audio-Graph
63 CPU <---> Codec
66 compatible = "audio-graph-card2";
72 bitclock-master;
73 frame-master;
74 cpu_ep: endpoint { remote-endpoint = <&codec_ep>; }; };
78 port { codec_ep: endpoint { remote-endpoint = <&cpu_ep>; }; };
82 Multi-CPU/Codec
88 +----+ +---+
89 CPU1 --|A X| <-@----> |x a|-- Codec1
90 CPU2 --|B | | b|-- Codec2
91 +----+ +---+
94 compatible = "audio-graph-card2";
99 ports@0 {
100 (@) mcpu: port@0 { mcpu0_ep: endpoint { remote-endpoint = <&mcodec0_ep>; }; }; // (X) to pair
101 port@1 { mcpu1_ep: endpoint { remote-endpoint = <&cpu1_ep>; }; }; // (A) Multi Element
102 port@2 { mcpu2_ep: endpoint { remote-endpoint = <&cpu2_ep>; }; }; // (B) Multi Element
104 ports@1 {
105 port@0 { mcodec0_ep: endpoint { remote-endpoint = <&mcpu0_ep>; }; }; // (x) to pair
106 port@1 { mcodec1_ep: endpoint { remote-endpoint = <&codec1_ep>; }; }; // (a) Multi Element
107 port@2 { mcodec2_ep: endpoint { remote-endpoint = <&codec2_ep>; }; }; // (b) Multi Element
113 ports {
114 bitclock-master;
115 frame-master;
116 port@0 { cpu1_ep: endpoint { remote-endpoint = <&mcpu1_ep>; }; };
117 port@1 { cpu2_ep: endpoint { remote-endpoint = <&mcpu2_ep>; }; };
122 ports {
123 port@0 { codec1_ep: endpoint { remote-endpoint = <&mcodec1_ep>; }; };
124 port@1 { codec2_ep: endpoint { remote-endpoint = <&mcodec2_ep>; }; };
134 PCM0 <--> * fe0 be0 * <--> DAI0: Codec Headset
135 PCM1 <--> * fe1 be1 * <--> DAI1: Codec Speakers
136 PCM2 <--> * fe2 be2 * <--> DAI2: MODEM
137 PCM3 <--> * fe3 be3 * <--> DAI3: BT
138 * be4 * <--> DAI4: DMIC
139 * be5 * <--> DAI5: FM
143 compatible = "audio-graph-card2";
150 // indicate all Front-End, Back-End
155 // Front-End
156 ports@0 {
157 fe0: port@0 { fe0_ep: endpoint { remote-endpoint = <&pcm0_ep>; }; };
158 fe1: port@1 { fe1_ep: endpoint { remote-endpoint = <&pcm1_ep>; }; };
161 // Back-End
162 ports@1 {
163 be0: port@0 { be0_ep: endpoint { remote-endpoint = <&dai0_ep>; }; };
164 be1: port@1 { be1_ep: endpoint { remote-endpoint = <&dai1_ep>; }; };
171 ports {
172 bitclock-master;
173 frame-master;
174 port@0 { pcm0_ep: endpoint { remote-endpoint = <&fe0_ep>; }; };
175 port@1 { pcm1_ep: endpoint { remote-endpoint = <&fe1_ep>; }; };
181 ports {
182 port@0 { dai0_ep: endpoint { remote-endpoint = <&be0_ep>; }; };
183 port@1 { dai1_ep: endpoint { remote-endpoint = <&be1_ep>; }; };
192 +--+
193 | |<-- Codec0 <- IN
194 | |--> Codec1 -> OUT
195 +--+
198 compatible = "audio-graph-card2";
206 ports {
208 c2c: port@0 { c2cf_ep: endpoint { remote-endpoint = <&codec0_ep>; }; };
209 port@1 { c2cb_ep: endpoint { remote-endpoint = <&codec1_ep>; }; };
214 ports {
216 bitclock-master;
217 frame-master;
218 codec0_ep: endpoint { remote-endpoint = <&c2cf_ep>; }; };
219 port@1 { codec1_ep: endpoint { remote-endpoint = <&c2cb_ep>; }; };
240 struct device_node *ports = of_get_parent(port);
242 if (!of_node_name_eq(ports, "ports")) {
243 of_node_put(ports);
246 return ports;
256 * ports {
263 if (of_node_name_eq(np, "ports")) {
271 fw_devlink_purge_absent_suppliers(&np->fwnode);
277 fw_devlink_purge_absent_suppliers(&np->fwnode);
283 fw_devlink_purge_absent_suppliers(&np->fwnode);
312 str = "DPCM Front-End";
314 str = "DPCM Back-End";
336 struct device_node *ports = port_to_ports(*port);
342 * ports {
355 *port = of_graph_get_next_port(ports, *port);
362 of_node_put(ports);
377 struct device_node *ports = port_to_ports(port);
378 struct simple_util_data *adata = &props->adata;
380 simple_util_parse_convert(ports, NULL, adata);
385 of_node_put(ports);
395 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link);
396 struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link);
428 if (!dai_link->name) {
434 if (dai_link->num_cpus > 1)
436 if (dai_link->num_codecs > 1)
443 simple_util_set_dailink_name(dev, dai_link, "%s%s-%s%s",
444 cpus->dai_name, cpu_multi,
445 codecs->dai_name, codec_multi);
450 cpus->of_node, cpus->dai_name, cpu_multi);
453 codecs->of_node, codecs->dai_name, codec_multi);
458 simple_util_set_dailink_name(dev, dai_link, "c2c.%s%s-%s%s",
459 cpus->dai_name, cpu_multi,
460 codecs->dai_name, codec_multi);
469 * if DPCM-BE case
477 snd_soc_of_parse_node_prefix(rports, cconf, codecs->of_node, "prefix");
478 snd_soc_of_parse_node_prefix(rport, cconf, codecs->of_node, "prefix");
500 * +---+ +---+
501 * | X|<-@------->|x |
503 * cpu0 <--|A 1|<--------->|4 a|-> codec0
504 * cpu1 <--|B 2|<-----+--->|5 b|-> codec1
505 * cpu2 <--|C 3|<----/ +---+
506 * +---+
509 * ports {
519 * ports {
536 int nm_max = max(dai_link->num_cpus, dai_link->num_codecs);
539 if (cpu_idx > dai_link->num_cpus) {
540 ret = -EINVAL;
560 ret = -EINVAL;
565 ret = -EINVAL;
572 if (codec_idx > dai_link->num_codecs)
576 dai_link->ch_maps[*nm_idx].cpu = cpu_idx;
577 dai_link->ch_maps[*nm_idx].codec = codec_idx;
606 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link);
609 int ret = -ENOMEM;
611 int nm_max = max(dai_link->num_cpus, dai_link->num_codecs);
617 if (gtype != GRAPH_DPCM && !dai_link->ch_maps &&
618 dai_link->num_cpus > 1 && dai_link->num_codecs > 1 &&
619 dai_link->num_cpus != dai_link->num_codecs) {
621 dai_link->ch_maps = devm_kcalloc(dev, nm_max,
623 if (!dai_link->ch_maps)
630 * ports {
638 * ports {
653 if (is_cpu && dai_link->ch_maps) {
660 if (is_cpu && dai_link->ch_maps && (nm_idx != nm_max))
661 ret = -EINVAL;
705 * ports {
721 * if (A) or (B) or (C) has bitclock-master / frame-master flag.
735 * This function is called by (C) -> (B) -> (A) order.
751 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link);
752 struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link);
798 of_property_read_u32(lnk, "mclk-fs", &dai_props->mclk_fs);
799 of_property_read_u32(ports_cpu, "mclk-fs", &dai_props->mclk_fs);
800 of_property_read_u32(ports_codec, "mclk-fs", &dai_props->mclk_fs);
801 of_property_read_u32(port_cpu, "mclk-fs", &dai_props->mclk_fs);
802 of_property_read_u32(port_codec, "mclk-fs", &dai_props->mclk_fs);
803 of_property_read_u32(ep_cpu, "mclk-fs", &dai_props->mclk_fs);
804 of_property_read_u32(ep_codec, "mclk-fs", &dai_props->mclk_fs);
823 dai_link->playback_only = playback_only;
824 dai_link->capture_only = capture_only;
826 dai_link->trigger_start = trigger_start;
827 dai_link->trigger_stop = trigger_stop;
829 dai_link->dai_fmt = daifmt | daiclk;
830 dai_link->init = simple_util_dai_init;
831 dai_link->ops = &graph_ops;
832 if (priv->ops)
833 dai_link->ops = priv->ops;
885 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link);
886 struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link);
895 * // Front-End
896 * ports@0 {
900 * // Back-End
901 * ports@0 {
907 * rports: ports {
917 dai_link->dynamic = 1;
918 dai_link->dpcm_merged_format = 1;
929 * // Front-End
930 * ports@0 {
933 * // Back-End
934 * ports@0 {
941 * rports: ports {
953 dai_link->no_pcm = 1;
954 dai_link->be_hw_params_fixup = simple_util_be_hw_params_fixup;
979 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link);
980 struct device_node *port0, *port1, *ports;
984 int ret = -EINVAL;
988 * ports {
996 * ports {
1004 ports = port_to_ports(port0);
1005 port1 = of_graph_get_next_port(ports, port0);
1015 of_property_read_u32(ports, "rate", &val);
1024 c2c_conf->formats = SNDRV_PCM_FMTBIT_S32_LE; /* update ME */
1025 c2c_conf->rates = SNDRV_PCM_RATE_8000_384000;
1026 c2c_conf->rate_min =
1027 c2c_conf->rate_max = val;
1028 c2c_conf->channels_min =
1029 c2c_conf->channels_max = 2; /* update ME */
1031 dai_link->c2c_params = c2c_conf;
1032 dai_link->num_c2c_params = 1;
1064 of_node_put(ports);
1080 int ret = -EINVAL;
1084 if (hooks && hooks->custom_normal)
1085 func = hooks->custom_normal;
1090 if (hooks && hooks->custom_dpcm)
1091 func = hooks->custom_dpcm;
1096 if (hooks && hooks->custom_c2c)
1097 func = hooks->custom_c2c;
1114 li->link++;
1125 * ports {
1136 struct device_node *ports = port_to_ports(lnk);
1142 return of_graph_get_port_count(ports) - 1;
1167 * simple-card.c :: simple_count_noml()
1169 li->num[li->link].cpus =
1170 li->num[li->link].platforms = graph_counter(cpu_port);
1172 li->num[li->link].codecs = graph_counter(codec_port);
1189 * // Front-End
1190 * ports@0 {
1194 * // Back-End
1195 * ports@1 {
1206 * simple-card.c :: simple_count_noml()
1208 li->num[li->link].cpus = graph_counter(rport); /* FE */
1209 li->num[li->link].platforms = graph_counter(rport);
1211 li->num[li->link].codecs = graph_counter(rport); /* BE */
1224 struct device_node *ports = port_to_ports(lnk);
1226 struct device_node *port1 = of_graph_get_next_port(ports, of_node_get(port0));
1234 * ports {
1243 * simple-card.c :: simple_count_noml()
1245 li->num[li->link].cpus =
1246 li->num[li->link].platforms = graph_counter(codec0);
1248 li->num[li->link].codecs = graph_counter(codec1);
1250 of_node_put(ports);
1268 int ret = -EINVAL;
1270 if (li->link >= SNDRV_MAX_LINKS) {
1298 li->link++;
1314 struct device_node *node = dev->of_node;
1341 return -ENOMEM;
1343 card->probe = graph_util_card_probe;
1344 card->owner = THIS_MODULE;
1345 card->dev = dev;
1347 if ((hooks) && (hooks)->hook_pre) {
1348 ret = (hooks)->hook_pre(priv);
1354 if (!li->link)
1355 ret = -EINVAL;
1363 priv->pa_gpio = devm_gpiod_get_optional(dev, "pa", GPIOD_OUT_LOW);
1364 if (IS_ERR(priv->pa_gpio)) {
1365 ret = PTR_ERR(priv->pa_gpio);
1389 if ((hooks) && (hooks)->hook_post) {
1390 ret = (hooks)->hook_post(priv);
1397 ret = snd_soc_of_parse_aux_devs(card, "aux-devs");
1413 struct device *dev = &pdev->dev;
1418 return -ENOMEM;
1424 { .compatible = "audio-graph-card2", },
1431 .name = "asoc-audio-graph-card2",
1440 MODULE_ALIAS("platform:asoc-audio-graph-card2");
1442 MODULE_DESCRIPTION("ASoC Audio Graph Card2");