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