• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2   Copyright(c) 2021 Intel Corporation
3   All rights reserved.
4 
5   This program is free software; you can redistribute it and/or modify
6   it under the terms of version 2 of the GNU General Public License as
7   published by the Free Software Foundation.
8 
9   This program is distributed in the hope that it will be useful, but
10   WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12   General Public License for more details.
13 
14   You should have received a copy of the GNU General Public License
15   along with this program; if not, write to the Free Software
16   Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17   The full GNU General Public License is included in this distribution
18   in the file called LICENSE.GPL.
19 */
20 #include "aconfig.h"
21 #include <errno.h>
22 #include <stdio.h>
23 #include <alsa/asoundlib.h>
24 #include "topology.h"
25 #include "pre-processor.h"
26 
tplg_build_hw_cfg_object(struct tplg_pre_processor * tplg_pp,snd_config_t * obj_cfg,snd_config_t * parent)27 int tplg_build_hw_cfg_object(struct tplg_pre_processor *tplg_pp,
28 			       snd_config_t *obj_cfg, snd_config_t *parent)
29 {
30 	snd_config_t *hw_cfg, *obj;
31 	const char *name;
32 	int ret;
33 
34 	obj = tplg_object_get_instance_config(tplg_pp, obj_cfg);
35 
36 	name = tplg_object_get_name(tplg_pp, obj);
37 	if (!name)
38 		return -EINVAL;
39 
40 	ret = tplg_build_object_from_template(tplg_pp, obj_cfg, &hw_cfg, NULL, false);
41 	if (ret < 0)
42 		return ret;
43 
44 	return tplg_parent_update(tplg_pp, parent, "hw_configs", name);
45 }
46 
tplg_build_fe_dai_object(struct tplg_pre_processor * tplg_pp,snd_config_t * obj_cfg,snd_config_t * parent)47 int tplg_build_fe_dai_object(struct tplg_pre_processor *tplg_pp, snd_config_t *obj_cfg,
48 			      snd_config_t *parent)
49 {
50 	return tplg_build_base_object(tplg_pp, obj_cfg, parent, false);
51 }
52 
tplg_update_pcm_object(struct tplg_pre_processor * tplg_pp,snd_config_t * obj_cfg,snd_config_t * parent)53 static int tplg_update_pcm_object(struct tplg_pre_processor *tplg_pp,
54 			       snd_config_t *obj_cfg, snd_config_t *parent)
55 {
56 	snd_config_t *top, *parent_obj, *obj, *dest, *cfg, *pcm, *child;
57 	const char *parent_name, *item_name, *direction;
58 	int ret;
59 
60 	/* get object name */
61 	obj = tplg_object_get_instance_config(tplg_pp, obj_cfg);
62 	item_name = tplg_object_get_name(tplg_pp, obj);
63 	if (!item_name)
64 		return -EINVAL;
65 
66 	/* get direction */
67 	ret = snd_config_search(obj, "direction", &cfg);
68 	if (ret < 0) {
69 		SNDERR("no direction attribute in %s\n", item_name);
70 		return ret;
71 	}
72 
73 	ret = snd_config_get_string(cfg, &direction);
74 	if (ret < 0) {
75 		SNDERR("Invalid direction attribute in %s\n", item_name);
76 		return ret;
77 	}
78 
79 	/* add to parent section */
80 	top = tplg_object_get_section(tplg_pp, parent);
81 	if (!top) {
82 		SNDERR("Cannot find parent for %s\n", item_name);
83 		return -EINVAL;
84 	}
85 
86 	parent_obj = tplg_object_get_instance_config(tplg_pp, parent);
87 
88 	/* get parent name. if parent has no name, skip adding config */
89 	parent_name = tplg_object_get_name(tplg_pp, parent_obj);
90 	if (!parent_name)
91 		return 0;
92 
93 	/* find parent config with name */
94 	dest = tplg_find_config(top, parent_name);
95 	if (!dest) {
96 		SNDERR("Cannot find parent section %s\n", parent_name);
97 		return -EINVAL;
98 	}
99 
100 	ret = snd_config_search(dest, "pcm", &pcm);
101 	if (ret < 0) {
102 		ret = tplg_config_make_add(&pcm, "pcm", SND_CONFIG_TYPE_COMPOUND, dest);
103 		if (ret < 0) {
104 			SNDERR("Error creating pcm config in %s\n", parent_name);
105 			return ret;
106 		}
107 	}
108 
109 	ret = snd_config_search(pcm, direction, &cfg);
110 	if (ret >= 0) {
111 		SNDERR("pcm.%s exists already in %s\n", direction, parent_name);
112 		return -EEXIST;
113 	}
114 
115 	ret = tplg_config_make_add(&cfg, direction, SND_CONFIG_TYPE_COMPOUND, pcm);
116 
117 	if (ret >= 0)
118 	ret = tplg_config_make_add(&child, "capabilities", SND_CONFIG_TYPE_STRING, cfg);
119 
120 	if (ret >= 0)
121 	ret = snd_config_set_string(child, item_name);
122 
123 	return ret;
124 }
125 
tplg_build_pcm_caps_object(struct tplg_pre_processor * tplg_pp,snd_config_t * obj_cfg,snd_config_t * parent)126 int tplg_build_pcm_caps_object(struct tplg_pre_processor *tplg_pp,
127 			       snd_config_t *obj_cfg, snd_config_t *parent)
128 {
129 	snd_config_t *caps;
130 	int ret;
131 
132 	ret = tplg_build_object_from_template(tplg_pp, obj_cfg, &caps, NULL, false);
133 	if (ret < 0)
134 		return ret;
135 
136 	/* add pcm capabilities to parent */
137 	return tplg_update_pcm_object(tplg_pp, obj_cfg, parent);
138 }
139