Re: [PATCH v3 16/20] ASoC: qdsp6: audioreach: add topology support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 8/3/2021 2:54 PM, Srinivas Kandagatla wrote:
Add ASoC topology support in audioreach

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@xxxxxxxxxx>
---

...

+
+/* DAI Tokens */
+#define AR_TKN_DAI_INDEX			1
+/* SUB GRAPH Tokens */
+#define AR_TKN_U32_SUB_GRAPH_INSTANCE_ID	2
+#define AR_TKN_U32_SUB_GRAPH_PERF_MODE		3
+#define AR_TKN_U32_SUB_GRAPH_DIRECTION		4
+#define AR_TKN_U32_SUB_GRAPH_SCENARIO_ID	5
+
+/* Container Tokens */
+#define AR_TKN_U32_CONAINER_INSTANCE_ID		100
+#define AR_TKN_U32_CONAINER_CAPABILITY_ID	101
+#define AR_TKN_U32_CONAINER_STACK_SIZE		102
+#define AR_TKN_U32_CONAINER_GRAPH_POS		103
+#define AR_TKN_U32_CONAINER_PROC_DOMAIN		104

typo in all of the above and in comment documenting them
AR_TKN_U32_CONTAINER_ *


  #define APM_AUDIO_DRV_NAME "q6apm-audio"
diff --git a/sound/soc/qcom/qdsp6/topology.c b/sound/soc/qcom/qdsp6/topology.c
new file mode 100644
index 000000000000..409e19486d57
--- /dev/null
+++ b/sound/soc/qcom/qdsp6/topology.c
@@ -0,0 +1,1114 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2020, Linaro Limited
+
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/pcm.h>
+#include <sound/control.h>
+#include <sound/asound.h>
+#include <linux/firmware.h>
+#include <sound/soc-topology.h>
+#include <sound/soc-dpcm.h>
+#include <uapi/sound/snd_ar_tokens.h>
+#include <linux/kernel.h>
+#include <linux/wait.h>
+#include "q6apm.h"
+#include "audioreach.h"
+
+struct snd_ar_control {
+	u32 sgid; /* Sub Graph ID */
+	struct snd_soc_component *scomp;
+};
+
+static struct audioreach_graph_info *audioreach_tplg_alloc_graph_info(
+					struct q6apm *apm, uint32_t graph_id,
+					bool *found)
+{
+	struct audioreach_graph_info *info;
+	int ret;
+
+	spin_lock(&apm->lock);
+	info = idr_find(&apm->graph_info_idr, graph_id);
+	spin_unlock(&apm->lock);
+
+	if (info) {
+		*found = true;
+		return info;
+	}
+
+	*found = false;
+	info = kzalloc(sizeof(*info), GFP_KERNEL);
+	if (!info)
+		return ERR_PTR(-ENOMEM);
+
+
+	INIT_LIST_HEAD(&info->sg_list);
+	spin_lock_init(&info->sg_list_lock);
+
+	spin_lock(&apm->lock);
+	ret = idr_alloc(&apm->graph_info_idr, info, graph_id,
+			graph_id + 1, GFP_ATOMIC);
+	spin_unlock(&apm->lock);
+
+	if (ret < 0) {
+		dev_err(apm->dev, "Failed to allocate Graph ID (%x)\n", graph_id);
+		return ERR_PTR(ret);
+	}
need to free info here?

+
+	info->id = ret;
+
+	return info;
+}
+
+static void audioreach_tplg_add_sub_graph(struct audioreach_sub_graph *sg,
+					  struct audioreach_graph_info *info)
+{
+	list_add_tail(&sg->node, &info->sg_list);
+	sg->info = info;
+	info->num_sub_graphs++;
+}
+
+
+static struct audioreach_sub_graph *audioreach_tplg_alloc_sub_graph(
+						struct q6apm *apm,
+						uint32_t sub_graph_id,
+						bool *found)
+{
+	struct audioreach_sub_graph *sg = NULL;
+	int ret;
+
+	if (!sub_graph_id)
+		return ERR_PTR(-EINVAL);
+
+	/* Find if there is already a matching sub-graph */
+	spin_lock(&apm->lock);
+	sg = idr_find(&apm->sub_graphs_idr, sub_graph_id);
+	spin_unlock(&apm->lock);
+
+
+	if (sg) {
+		*found = true;
+		return sg;
+	}
+
+	*found = false;
+	sg = kzalloc(sizeof(*sg), GFP_KERNEL);
+	if (!sg)
+		return ERR_PTR(-ENOMEM);
+
+	INIT_LIST_HEAD(&sg->container_list);
+
+	spin_lock(&apm->lock);
+	ret = idr_alloc(&apm->sub_graphs_idr, sg, sub_graph_id,
+			sub_graph_id + 1, GFP_ATOMIC);
+	spin_unlock(&apm->lock);
+
+	if (ret < 0) {
+		dev_err(apm->dev,
+			"Failed to allocate Sub-Graph Instance ID (%x)\n",
+			sub_graph_id);
+		return ERR_PTR(ret);
+	}
need to free sg here?

+
+	sg->sub_graph_id = ret;
+
+	return sg;
+}
+
+static struct audioreach_container *audioreach_tplg_alloc_container(struct q6apm *apm,
+						struct audioreach_sub_graph *sg,
+						uint32_t container_id,
+						bool *found)
+{
+	struct audioreach_container *cont = NULL;
+	int ret;
+
+	if (!container_id)
+		return ERR_PTR(-EINVAL);
+
+	spin_lock(&apm->lock);
+	cont = idr_find(&apm->containers_idr, container_id);
+	spin_unlock(&apm->lock);
+
+	if (cont) {
+		*found = true;
+		return cont;
+	}
+	*found = false;
+
+	cont = kzalloc(sizeof(*cont), GFP_KERNEL);
+	if (!cont)
+		return ERR_PTR(-ENOMEM);
+
+	INIT_LIST_HEAD(&cont->modules_list);
+
+	spin_lock(&apm->lock);
+	ret = idr_alloc(&apm->containers_idr, cont, container_id,
+				container_id + 1, GFP_ATOMIC);
+	spin_unlock(&apm->lock);
+
+	if (ret < 0) {
+		dev_err(apm->dev,
+			"Failed to allocate Container Instance ID (%x)\n",
+			container_id);
+		return ERR_PTR(ret);
+	}
need to free cont here?
+
+	cont->container_id = ret;
+	cont->sub_graph = sg;
+	/* add to container list */
+	list_add_tail(&cont->node, &sg->container_list);
+	sg->num_containers++;
+
+	return cont;
+}
+
+static struct audioreach_module *audioreach_tplg_alloc_module(struct q6apm *apm,
+					struct audioreach_container *cont,
+					struct snd_soc_dapm_widget *w,
+					uint32_t module_id,
+					bool *found)
+{
+	struct audioreach_module *mod;
+	int ret;
+
+	spin_lock(&apm->lock);
+	mod = idr_find(&apm->modules_idr, module_id);
+	spin_unlock(&apm->lock);
+
+	if (mod) {
+		*found = true;
+		return mod;
+	}
+	*found = false;
+	mod = kzalloc(sizeof(*mod), GFP_KERNEL);
+	if (!mod)
+		return ERR_PTR(-ENOMEM);
+
+	spin_lock(&apm->lock);
+	if (!module_id) { /* alloc module id dynamically */
+		ret = idr_alloc_cyclic(&apm->modules_idr, mod,
+				       AR_MODULE_DYNAMIC_INSTANCE_ID_START,
+				       AR_MODULE_DYNAMIC_INSTANCE_ID_END,
+				       GFP_ATOMIC);
+	} else {
+		ret = idr_alloc(&apm->modules_idr, mod, module_id,
+			  module_id + 1, GFP_ATOMIC);
+	}
+	spin_unlock(&apm->lock);
+
+	if (ret < 0) {
+		dev_err(apm->dev,
+			"Failed to allocate Module Instance ID (%x)\n", module_id);
+		return ERR_PTR(ret);
+	}
need to free mod here?

+
+	mod->instance_id = ret;
+	dev_err(apm->dev, "Module Instance ID (0x%08x) allocated\n", ret);
+	/* add to module list */
+	list_add_tail(&mod->node, &cont->modules_list);
+	mod->container = cont;
+	mod->widget = w;
+	cont->num_modules++;
+
+	return mod;
+}
+

...




[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]


  Powered by Linux