From 51951b3e431d43279da15c33daebf35c6fd94f7b Mon Sep 17 00:00:00 2001
From: Daniel Baluta <daniel.baluta@nxp.com>
Date: Thu, 4 Oct 2018 12:16:42 +0300
Subject: [PATCH] MLK-18497-7: ASoC: fsl: xaf_afi: Introduce component API

This is based on Xtensa Audio framework
userspace implemention API.

Reviewed-by: Cosmin-Gabriel Samoila <cosmin.samoila@nxp.com>
Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com
Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com>
(cherry picked from commit 83b6f7340c4bb5fd9380cce5d856b18b9dc34457)
TODO: checkpatch warnings
Signed-off-by: Vipul Kumar <vipul_kumar@mentor.com>
Signed-off-by: Srikanth Krishnakar <Srikanth_Krishnakar@mentor.com>
Signed-off-by: Vipul Kumar <vipul_kumar@mentor.com>
---
 include/uapi/linux/mxc_dsp.h    |   3 +
 sound/soc/fsl/Makefile          |   2 +-
 sound/soc/fsl/fsl_dsp_xaf_api.c | 473 ++++++++++++++++++++++++++++++++
 sound/soc/fsl/fsl_dsp_xaf_api.h | 134 +++++++++
 4 files changed, 611 insertions(+), 1 deletion(-)
 create mode 100644 sound/soc/fsl/fsl_dsp_xaf_api.c
 create mode 100644 sound/soc/fsl/fsl_dsp_xaf_api.h

diff --git a/include/uapi/linux/mxc_dsp.h b/include/uapi/linux/mxc_dsp.h
index e328c7fe2447a6..35c6bdfd57692e 100644
--- a/include/uapi/linux/mxc_dsp.h
+++ b/include/uapi/linux/mxc_dsp.h
@@ -46,6 +46,9 @@
 #define CODEC_SBC_ENC		8
 #define CODEC_DEMO_DEC		9
 
+#define RENDER_ESAI		0x10
+#define RENDER_SAI		0x11
+
 enum DSP_ERROR_TYPE {
 	XA_SUCCESS = 0,
 
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index 144a4931ae6ed8..dfe7ebe33092b6 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -17,7 +17,7 @@ snd-soc-fsl-amix-objs := fsl_amix.o
 snd-soc-fsl-asrc-objs := fsl_asrc.o fsl_asrc_dma.o
 snd-soc-fsl-dma-workaround-objs := fsl_dma_workaround.o
 snd-soc-fsl-dsp-objs := fsl_dsp.o fsl_dsp_proxy.o fsl_dsp_pool.o \
-	fsl_dsp_library_load.o
+	fsl_dsp_library_load.o fsl_dsp_xaf_api.o
 snd-soc-fsl-sai-objs := fsl_sai.o
 snd-soc-fsl-ssi-y := fsl_ssi.o
 snd-soc-fsl-ssi-$(CONFIG_DEBUG_FS) += fsl_ssi_dbg.o
diff --git a/sound/soc/fsl/fsl_dsp_xaf_api.c b/sound/soc/fsl/fsl_dsp_xaf_api.c
new file mode 100644
index 00000000000000..503503a28922d4
--- /dev/null
+++ b/sound/soc/fsl/fsl_dsp_xaf_api.c
@@ -0,0 +1,473 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+//
+// Xtensa Audio Framework API for communication with DSP
+//
+// Copyright (C) 2017 Cadence Design Systems, Inc.
+// Copyright 2018 NXP
+
+#include "fsl_dsp.h"
+#include "fsl_dsp_xaf_api.h"
+
+/* ...send a command message to component */
+int xf_command(struct xf_client *client, struct xf_handle *handle,
+	       u32 port, u32 opcode, void *buffer, u32 length)
+{
+	struct xf_proxy *proxy = handle->proxy;
+	struct xf_message  msg;
+
+	/* ...fill-in message parameters */
+	msg.id = __XF_MSG_ID(__XF_AP_CLIENT(0, 0),
+				__XF_PORT_SPEC2(handle->id, port));
+	msg.id = XF_MSG_AP_FROM_USER(msg.id, client->id);
+	msg.opcode = opcode;
+	msg.length = length;
+	msg.buffer = buffer;
+	msg.ret = 0;
+
+	/* ...execute command synchronously */
+	return xf_cmd_send(proxy, msg.id, msg.opcode, msg.buffer, msg.length);
+}
+
+int xaf_comp_set_config(struct xf_client *client, struct xaf_comp *p_comp,
+			u32 num_param, void *p_param)
+{
+	struct xf_handle *p_handle;
+	struct xf_message msg;
+	struct xf_message *rmsg;
+	struct xf_set_param_msg *smsg;
+	struct xf_set_param_msg *param = (struct xf_set_param_msg *)p_param;
+	struct xf_proxy *proxy;
+	u32 i;
+
+	p_handle = &p_comp->handle;
+	proxy = p_handle->proxy;
+
+	/* ...set persistent stream characteristics */
+	smsg = xf_buffer_data(p_handle->aux);
+
+	for (i = 0; i < num_param; i++) {
+		smsg[i].id = param[i].id;
+		smsg[i].value = param[i].value;
+	}
+
+	/* ...set command parameters */
+	msg.id = __XF_MSG_ID(__XF_AP_CLIENT(0, 0),
+				__XF_PORT_SPEC2(p_handle->id, 0));
+	msg.id = XF_MSG_AP_FROM_USER(msg.id, client->id);
+	msg.opcode = XF_SET_PARAM;
+	msg.length = sizeof(*smsg) * num_param;
+	msg.buffer = smsg;
+	msg.ret = 0;
+
+	/* ...execute command synchronously */
+	rmsg = xf_cmd_send_recv_complete(client, proxy, msg.id, msg.opcode,
+					 msg.buffer, msg.length, &client->work,
+					 &client->compr_complete);
+
+	if(IS_ERR(rmsg))
+		return PTR_ERR(rmsg);
+	/* ...save received component global client-id */
+	/* TODO: review cleanup */
+	/* xf_msg_free(proxy, rmsg);
+	 * xf_unlock(&proxy->lock);
+	 */
+
+	/* ...make sure response is expected */
+	if ((rmsg->opcode != XF_SET_PARAM) || (rmsg->buffer != smsg)) {
+		return -EPIPE;
+	}
+
+	return 0;
+}
+
+int xaf_comp_get_config(struct xf_client *client, struct xaf_comp *p_comp,
+			u32 num_param, void *p_param)
+{
+
+	struct xf_handle *p_handle;
+	struct xf_message msg;
+	struct xf_message *rmsg;
+	struct xf_get_param_msg *smsg;
+	struct xf_get_param_msg *param = (struct xf_get_param_msg *)p_param;
+	struct xf_proxy *proxy;
+	u32 i;
+
+	p_handle = &p_comp->handle;
+	proxy = p_handle->proxy;
+
+	/* ...set persistent stream characteristics */
+	smsg = xf_buffer_data(p_handle->aux);
+
+	for (i = 0; i < num_param; i++)
+		smsg[i].id = param[i].id;
+
+
+	msg.id = __XF_MSG_ID(__XF_AP_CLIENT(0, 0),
+				__XF_PORT_SPEC2(p_handle->id, 0));
+	msg.id = XF_MSG_AP_FROM_USER(msg.id, client->id);
+	msg.opcode = XF_GET_PARAM;
+	msg.length = sizeof(*smsg) * num_param;
+	msg.buffer = smsg;
+	msg.ret = 0;
+
+	/* ...execute command synchronously */
+	rmsg = xf_cmd_send_recv_complete(client, proxy, msg.id, msg.opcode,
+					 msg.buffer, msg.length, &client->work,
+					 &client->compr_complete);
+
+	/* ...save received component global client-id */
+	if(IS_ERR(rmsg))
+		return PTR_ERR(rmsg);
+
+	/* TODO: review cleanup */
+	/* xf_msg_free(proxy, rmsg);
+	 * xf_unlock(&proxy->lock); */
+
+	/* ...make sure response is expected */
+	if ((rmsg->opcode != (u32)XF_GET_PARAM) || (rmsg->buffer != smsg)) {
+		return -EPIPE;
+	}
+
+	for (i = 0; i < num_param; i++)
+		param[i].value = smsg[i].value;
+
+	return 0;
+}
+
+int xaf_comp_flush(struct xf_client *client, struct xaf_comp *p_comp)
+{
+
+	struct xf_handle       *p_handle;
+	struct xf_proxy        *proxy;
+	struct xf_message     msg;
+	struct xf_message     *rmsg;
+
+	p_handle = &p_comp->handle;
+	proxy = p_handle->proxy;
+
+	msg.id = __XF_MSG_ID(__XF_AP_CLIENT(0, 0),
+				__XF_PORT_SPEC2(p_handle->id, 0));
+	msg.id = XF_MSG_AP_FROM_USER(msg.id, client->id);
+	msg.opcode = XF_FLUSH;
+	msg.length = 0;
+	msg.buffer = NULL;
+	msg.ret = 0;
+
+
+	/* ...execute command synchronously */
+	rmsg = xf_cmd_send_recv_complete(client, proxy, msg.id, msg.opcode,
+					 msg.buffer, msg.length, &client->work,
+					 &client->compr_complete);
+
+	if(IS_ERR(rmsg))
+		return PTR_ERR(rmsg);
+	
+	/* ...make sure response is expected */
+	if ((rmsg->opcode != (u32)XF_FLUSH) || rmsg->buffer) {
+		return -EPIPE;
+	}
+
+	return 0;
+}
+
+int xaf_comp_create(struct xf_client *client, struct xf_proxy *proxy,
+		    struct xaf_comp *p_comp, int comp_type)
+{
+	struct fsl_dsp *dsp_priv = container_of(proxy, struct fsl_dsp, proxy);
+	char   lib_path[200];
+	char   lib_wrap_path[200];
+	struct xf_handle *p_handle;
+	struct xf_buffer *buf;
+	int    ret = 0;
+	bool   loadlib = true;
+
+	memset((void *)p_comp, 0, sizeof(struct xaf_comp));
+
+	strcpy(lib_path, "/lib/firmware/imx/dsp/");
+	strcpy(lib_wrap_path, "/lib/firmware/imx/dsp/");
+
+	p_handle = &p_comp->handle;
+
+	p_comp->comp_type = comp_type;
+
+	if (comp_type == RENDER_ESAI)
+		loadlib = false;
+
+	if (loadlib) {
+		p_comp->codec_lib.filename      = lib_path;
+		p_comp->codec_wrap_lib.filename = lib_wrap_path;
+		p_comp->codec_lib.lib_type      = DSP_CODEC_LIB;
+	}
+
+	switch (comp_type) {
+	case CODEC_MP3_DEC:
+		p_comp->dec_id = "audio-decoder/mp3";
+		strcat(lib_path, "lib_dsp_mp3_dec.so");
+		break;
+	case CODEC_AAC_DEC:
+		p_comp->dec_id = "audio-decoder/aac";
+		strcat(lib_path, "lib_dsp_aac_dec.so");
+		break;
+	case RENDER_ESAI:
+		p_comp->dec_id = "renderer/esai";
+		break;
+
+	default:
+		return -EINVAL;
+		break;
+	}
+
+	/* ...create decoder component instance (select core-0) */
+	ret = xf_open(client, proxy, p_handle, p_comp->dec_id, 0, NULL);
+	if (ret) {
+		dev_err(dsp_priv->dev, "create (%s) component error: %d\n",
+			p_comp->dec_id, ret);
+		return ret;
+	}
+
+	if (loadlib) {
+		strcat(lib_wrap_path, "lib_dsp_codec_wrap.so");
+		p_comp->codec_wrap_lib.lib_type = DSP_CODEC_WRAP_LIB;
+
+		/* ...load codec wrapper lib */
+		ret = xf_load_lib(client, p_handle, &p_comp->codec_wrap_lib);
+		if (ret) {
+			dev_err(dsp_priv->dev, "load codec wrap lib error\n");
+			return ret;
+		}
+
+		/* ...load codec lib */
+		ret = xf_load_lib(client, p_handle, &p_comp->codec_lib);
+		if (ret) {
+			dev_err(dsp_priv->dev, "load codec lib error\n");
+			return ret;
+		}
+
+		/* ...allocate input buffer */
+		ret = xf_pool_alloc(client, proxy, 1, INBUF_SIZE,
+				    XF_POOL_INPUT, &p_comp->inpool);
+		if (ret) {
+			dev_err(dsp_priv->dev, "alloc input buf error\n");
+			return ret;
+		}
+
+		/* ...initialize input buffer pointer */
+		buf = xf_buffer_get(p_comp->inpool);
+		p_comp->inptr = xf_buffer_data(buf);
+	}
+
+	return ret;
+}
+
+int xaf_comp_delete(struct xf_client *client, struct xaf_comp *p_comp)
+{
+
+	struct xf_handle *p_handle;
+	bool   loadlib = true;
+	u32 ret = 0;
+
+	if (p_comp->comp_type == RENDER_ESAI)
+		loadlib = false;
+
+	p_handle = &p_comp->handle;
+
+	if (loadlib) {
+		/* ...unload codec wrapper library */
+		xf_unload_lib(client, p_handle, &p_comp->codec_wrap_lib);
+
+		/* ...unload codec library */
+		xf_unload_lib(client, p_handle, &p_comp->codec_lib);
+
+		xf_pool_free(client, p_comp->inpool);
+	}
+
+	/* ...delete component */
+	xf_close(client, p_handle);
+
+	return ret;
+}
+
+int xaf_comp_process(struct xf_client *client, struct xaf_comp *p_comp, void *p_buf, u32 length, u32 flag)
+{
+	struct xf_handle *p_handle;
+	u32 ret = 0;
+
+	p_handle = &p_comp->handle;
+
+	switch (flag) {
+	case XF_FILL_THIS_BUFFER:
+		/* ...send message to component output port (port-id=1) */
+		ret = xf_command(client, p_handle, 1, XF_FILL_THIS_BUFFER,
+				 p_buf, length);
+		break;
+	case XF_EMPTY_THIS_BUFFER:
+		/* ...send message to component input port (port-id=0) */
+		ret = xf_command(client, p_handle, 0, XF_EMPTY_THIS_BUFFER,
+				 p_buf, length);
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+/* ...port binding function */
+int xf_route(struct xf_client *client, struct xf_handle *src, u32 src_port,
+	     struct xf_handle *dst, u32 dst_port, u32 num, u32 size, u32 align)
+{
+	struct xf_proxy *proxy = src->proxy;
+	struct xf_buffer *b;
+	struct xf_route_port_msg *m;
+	struct xf_message msg;
+	struct xf_message *rmsg;
+
+	/* ...sanity checks - proxy pointers are same */
+	if (proxy != dst->proxy)
+		return -EINVAL;
+
+	/* ...buffer data is sane */
+	if (!(num && size && xf_is_power_of_two(align)))
+		return -EINVAL;
+
+	/* ...get control buffer */
+	if ((b = xf_buffer_get(proxy->aux)) == NULL)
+		return -EBUSY;
+
+	/* ...get message buffer */
+	m = xf_buffer_data(b);
+
+	/* ...fill-in message parameters */
+	m->src = __XF_PORT_SPEC2(src->id, src_port);
+	m->dst = __XF_PORT_SPEC2(dst->id, dst_port);
+	m->alloc_number = num;
+	m->alloc_size = size;
+	m->alloc_align = align;
+
+	/* ...set command parameters */
+	msg.id = __XF_MSG_ID(__XF_AP_PROXY(0),
+			     __XF_PORT_SPEC2(src->id, src_port));
+	msg.id = XF_MSG_AP_FROM_USER(msg.id, client->id);
+	msg.opcode = XF_ROUTE;
+	msg.length = sizeof(*m);
+	msg.buffer = m;
+	msg.ret = 0;
+
+	/* ...execute command synchronously */
+	rmsg = xf_cmd_send_recv_complete(client, proxy, msg.id, msg.opcode,
+					 msg.buffer, msg.length, &client->work,
+					 &client->compr_complete);
+	if(IS_ERR(rmsg))
+		return PTR_ERR(rmsg);
+
+	/* ...save received component global client-id */
+	/* TODO: review cleanup */
+	/* xf_msg_free(proxy, rmsg);
+	 * xf_unlock(&proxy->lock); */
+
+
+        /* ...synchronously execute command on remote DSP */
+	/* XF_CHK_API(xf_proxy_cmd_exec(proxy, &msg)); */
+
+	/* ...return buffer to proxy */
+	xf_buffer_put(b);
+
+        /* ...check result is successful */
+	/* XF_CHK_ERR(msg.opcode == XF_ROUTE, -ENOMEM); */
+
+	return 0;
+}
+
+/* ...port unbinding function */
+int xf_unroute(struct xf_client *client, struct xf_handle *src, u32 src_port)
+{
+	struct xf_proxy        *proxy = src->proxy;
+	struct xf_buffer       *b;
+	struct xf_unroute_port_msg  *m;
+	struct xf_message      msg;
+	struct xf_message     *rmsg;
+	int                  r = 0;
+
+	/* ...get control buffer */
+	if((b = xf_buffer_get(proxy->aux)) == NULL)
+		return -EBUSY;
+
+	/* ...get message buffer */
+	m = xf_buffer_data(b);
+
+	/* ...fill-in message parameters */
+	m->src = __XF_PORT_SPEC2(src->id, src_port);
+
+	/* ...set command parameters */
+	msg.id = __XF_MSG_ID(__XF_AP_PROXY(0),
+			__XF_PORT_SPEC2(src->id, src_port));
+	msg.id = XF_MSG_AP_FROM_USER(msg.id, client->id);
+	msg.opcode = XF_UNROUTE;
+	msg.length = sizeof(*m);
+	msg.buffer = m;
+	msg.ret = 0;
+
+	/* ...execute command synchronously */
+	rmsg = xf_cmd_send_recv_complete(client, proxy, msg.id, msg.opcode,
+					 msg.buffer, msg.length, &client->work,
+					 &client->compr_complete);
+	if (IS_ERR(rmsg))
+		return PTR_ERR(rmsg);
+	/* ...save received component global client-id */
+
+	/*TODO: review cleanup */
+	/* xf_msg_free(proxy, rmsg); */
+	/* xf_unlock(&proxy->lock); */
+
+        /* ...return buffer to proxy */
+        xf_buffer_put(b);
+
+        return r;
+}
+
+int xaf_connect(struct xf_client *client,
+		struct xaf_comp *p_src,
+		struct xaf_comp *p_dest,
+		u32 num_buf,
+		u32 buf_length)
+{
+	/* ...connect p_src output port with p_dest input port */
+	return xf_route(client, &p_src->handle, 0, &p_dest->handle, 0,
+			num_buf, buf_length, 8);
+}
+
+int xaf_disconnect(struct xf_client *client, struct xaf_comp *p_comp)
+{
+	/* ...disconnect p_src output port with p_dest input port */
+	return xf_unroute(client, &p_comp->handle, 0);
+
+}
+
+int xaf_comp_add(struct xaf_pipeline *p_pipe, struct xaf_comp *p_comp)
+{
+	int ret = 0;
+
+	p_comp->next = p_pipe->comp_chain;
+	p_comp->pipeline = p_pipe;
+	p_pipe->comp_chain = p_comp;
+
+	return ret;
+}
+
+int xaf_pipeline_create(struct xaf_pipeline *p_pipe)
+{
+	int ret = 0;
+
+	memset(p_pipe, 0, sizeof(struct xaf_pipeline));
+
+	return ret;
+}
+
+int xaf_pipeline_delete(struct xaf_pipeline *p_pipe)
+{
+	int ret = 0;
+
+	memset(p_pipe, 0, sizeof(struct xaf_pipeline));
+
+	return ret;
+}
diff --git a/sound/soc/fsl/fsl_dsp_xaf_api.h b/sound/soc/fsl/fsl_dsp_xaf_api.h
new file mode 100644
index 00000000000000..5087b46520d589
--- /dev/null
+++ b/sound/soc/fsl/fsl_dsp_xaf_api.h
@@ -0,0 +1,134 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT)*/
+/*
+ * Xtensa Audio Framework API for communication with DSP
+ *
+ * Copyright (C) 2017 Cadence Design Systems, Inc.
+ * Copyright 2018 NXP
+ */
+#ifndef FSL_DSP_XAF_API_H
+#define FSL_DSP_XAF_API_H
+
+#include "fsl_dsp_library_load.h"
+
+/* ...size of auxiliary pool for communication with DSP */
+#define XA_AUX_POOL_SIZE	32
+
+/* ...length of auxiliary pool messages */
+#define XA_AUX_POOL_MSG_LENGTH	128
+
+/* ...number of max input buffers */
+#define INBUF_SIZE	4096
+#define OUTBUF_SIZE	16384
+
+struct xaf_pipeline;
+
+struct xaf_info_s {
+	u32 opcode;
+	void *buf;
+	u32 length;
+	u32 ret;
+};
+
+struct xaf_comp {
+	struct xaf_comp *next;
+
+	struct xaf_pipeline *pipeline;
+	struct xf_handle handle;
+
+	const char *dec_id;
+	int comp_type;
+
+	struct xf_pool *inpool;
+	struct xf_pool *outpool;
+	void *inptr;
+	void *outptr;
+
+	struct lib_info codec_lib;
+	struct lib_info codec_wrap_lib;
+};
+
+struct xaf_pipeline {
+	struct xaf_comp *comp_chain;
+
+	u32 input_eos;
+	u32 output_eos;
+};
+
+int xaf_comp_create(struct xf_client *client, struct xf_proxy *p_proxy,
+		    struct xaf_comp *p_comp, int comp_type);
+int xaf_comp_delete(struct xf_client *client, struct xaf_comp *p_comp);
+int xaf_comp_flush(struct xf_client *client, struct xaf_comp *p_comp);
+
+int xaf_comp_set_config(struct xf_client *client,struct xaf_comp *p_comp,
+			u32 num_param, void *p_param);
+int xaf_comp_get_config(struct xf_client *client,struct xaf_comp *p_comp,
+			u32 num_param, void *p_param);
+
+int xaf_comp_add(struct xaf_pipeline *p_pipe, struct xaf_comp *p_comp);
+int xaf_comp_process(struct xf_client *client, struct xaf_comp *p_comp,
+		     void *p_buf, u32 length, u32 flag);
+int xaf_comp_get_status(struct xaf_comp *p_comp, struct xaf_info_s *p_info);
+int xaf_comp_get_msg_count(struct xaf_comp *p_comp);
+
+int xaf_connect(struct xf_client *client,struct xaf_comp *p_src,
+		struct xaf_comp *p_dest, u32 num_buf, u32 buf_length);
+int xaf_disconnect(struct xf_client *client,struct xaf_comp *p_comp);
+
+int xaf_pipeline_create(struct xaf_pipeline *p_pipe);
+int xaf_pipeline_delete(struct xaf_pipeline *p_pipe);
+
+int xaf_pipeline_send_eos(struct xaf_pipeline *p_pipe);
+
+/* ...port routing command */
+struct __attribute__((__packed__)) xf_route_port_msg {
+	/* ...source port specification */
+	u32 src;
+	/* ...destination port specification */
+	u32 dst;
+	/* ...number of buffers to allocate */
+	u32 alloc_number;
+	/* ...length of buffer to allocate */
+	u32 alloc_size;
+	/* ...alignment restriction for a buffer */
+	u32 alloc_align;
+};
+
+/* ...port unrouting command */
+struct __attribute__((__packed__)) xf_unroute_port_msg {
+	/* ...source port specification */
+	u32 src;
+	/* ...destination port specification */
+	u32 dst;
+};
+
+/* ...check if non-zero value is a power-of-two */
+#define xf_is_power_of_two(v)       (((v) & ((v) - 1)) == 0)
+
+/* ...component initialization parameter */
+struct __attribute__((__packed__)) xf_set_param_msg {
+	/* ...index of parameter passed to SET_CONFIG_PARAM call */
+	u32 id;
+	/* ...value of parameter */
+	u32 value;
+};
+
+/* ...message body (command/response) */
+struct __attribute__((__packed__)) xf_get_param_msg {
+	/* ...array of parameters requested */
+	u32 id;
+	/* ...array of parameters values */
+	u32 value;
+};
+
+/* ...renderer-specific configuration parameters */
+enum xa_config_param_renderer {
+	XA_RENDERER_CONFIG_PARAM_CB             = 0,
+	XA_RENDERER_CONFIG_PARAM_STATE          = 1,
+	XA_RENDERER_CONFIG_PARAM_PCM_WIDTH      = 2,
+	XA_RENDERER_CONFIG_PARAM_CHANNELS       = 3,
+	XA_RENDERER_CONFIG_PARAM_SAMPLE_RATE    = 4,
+	XA_RENDERER_CONFIG_PARAM_FRAME_SIZE     = 5,
+	XA_RENDERER_CONFIG_PARAM_NUM            = 6,
+};
+
+#endif /* FSL_DSP_XAF_API_H */
-- 
GitLab