All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] ASoC: Intel: Skylake: Add token support for topology data
@ 2016-08-12  6:59 Vinod Koul
  2016-08-12  6:59 ` [PATCH 1/4] ASoC: uapi: Intel: Skylake: Define vendor specific tokens Vinod Koul
                   ` (4 more replies)
  0 siblings, 5 replies; 15+ messages in thread
From: Vinod Koul @ 2016-08-12  6:59 UTC (permalink / raw)
  To: alsa-devel; +Cc: liam.r.girdwood, patches.audio, broonie, Vinod Koul

With topology changes in alsa-lib, driver data for modules can now be
passed in topology conf file using tuples.

These changes allow private data to represented by tuples of type UUID,
byte, short, word and strings.

This patch series adds changes to:
 - Define vendor tokens to best describe module private data
 - Parse these token value to populate module private data
 - Remove the skl_dfw_config structure as it would no longer be required.
 - Define tokens for manifest private data and parse them to populate
   library names for library loading.

Shreyas NC (4):
  ASoC: uapi: Intel: Skylake: Define vendor specific tokens
  ASoC: Intel: Skylake: Parse vendor tokens to build module data
  ASoC: Intel: Skylake: Remove dfw config and associated structures
  ASoC: Intel: Skylake: Parse manifest data

 include/uapi/sound/Kbuild                    |   1 +
 include/uapi/sound/snd_sst_tokens.h          | 214 +++++++
 sound/soc/intel/skylake/skl-sst-utils.c      |   5 -
 sound/soc/intel/skylake/skl-topology.c       | 839 +++++++++++++++++++++++----
 sound/soc/intel/skylake/skl-tplg-interface.h |  83 +--
 5 files changed, 953 insertions(+), 189 deletions(-)
 create mode 100644 include/uapi/sound/snd_sst_tokens.h

-- 
1.9.1

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 1/4] ASoC: uapi: Intel: Skylake: Define vendor specific tokens
  2016-08-12  6:59 [PATCH 0/4] ASoC: Intel: Skylake: Add token support for topology data Vinod Koul
@ 2016-08-12  6:59 ` Vinod Koul
  2016-08-22 17:59   ` Applied "ASoC: uapi: Intel: Skylake: Define vendor specific tokens" to the asoc tree Mark Brown
  2016-08-12  6:59 ` [PATCH 2/4] ASoC: Intel: Skylake: Parse vendor tokens to build module data Vinod Koul
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 15+ messages in thread
From: Vinod Koul @ 2016-08-12  6:59 UTC (permalink / raw)
  To: alsa-devel
  Cc: liam.r.girdwood, patches.audio, broonie, Vinod Koul, Shreyas NC

From: Shreyas NC <shreyas.nc@intel.com>

With recent topology changes in alsa-lib, driver data for
modules can now be passed in topology conf file using tuples.

This patch defines vendor specific tokens to describe private
data with tuples.

The allowed token types are UUID, string, bool, byte, short and
word. These tokens will be referenced by the vendor tuples in
the conf file.

In the topology conf file, multiple data blocks can be defined
for a widget which can be either tuple vendor array or blob. So,
each data block will be preceded by a descriptor to identify
size and type of block. These descriptors will be token
value pairs.

Tokens for module_id and loadable flag are not defined as these
are read from the DSP FW manifest.

Signed-off-by: Shreyas NC <shreyas.nc@intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
---
 include/uapi/sound/Kbuild           |   1 +
 include/uapi/sound/snd_sst_tokens.h | 208 ++++++++++++++++++++++++++++++++++++
 2 files changed, 209 insertions(+)
 create mode 100644 include/uapi/sound/snd_sst_tokens.h

diff --git a/include/uapi/sound/Kbuild b/include/uapi/sound/Kbuild
index 691984cb0b91..9578d8bdbf31 100644
--- a/include/uapi/sound/Kbuild
+++ b/include/uapi/sound/Kbuild
@@ -13,3 +13,4 @@ header-y += sb16_csp.h
 header-y += sfnt_info.h
 header-y += tlv.h
 header-y += usb_stream.h
+header-y += snd_sst_tokens.h
diff --git a/include/uapi/sound/snd_sst_tokens.h b/include/uapi/sound/snd_sst_tokens.h
new file mode 100644
index 000000000000..f56a932736ca
--- /dev/null
+++ b/include/uapi/sound/snd_sst_tokens.h
@@ -0,0 +1,208 @@
+/*
+ * snd_sst_tokens.h - Intel SST tokens definition
+ *
+ * Copyright (C) 2016 Intel Corp
+ * Author: Shreyas NC <shreyas.nc@intel.com>
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+#ifndef __SND_SST_TOKENS_H__
+#define __SND_SST_TOKENS_H__
+
+/**
+ * %SKL_TKN_UUID:               Module UUID
+ *
+ * %SKL_TKN_U8_BLOCK_TYPE:      Type of the private data block.Can be:
+ *                              tuples, bytes, short and words
+ *
+ * %SKL_TKN_U8_IN_PIN_TYPE:     Input pin type,
+ *                              homogenous=0, heterogenous=1
+ *
+ * %SKL_TKN_U8_OUT_PIN_TYPE:    Output pin type,
+ *                              homogenous=0, heterogenous=1
+ * %SKL_TKN_U8_DYN_IN_PIN:      Configure Input pin dynamically
+ *                              if true
+ *
+ * %SKL_TKN_U8_DYN_OUT_PIN:     Configure Output pin dynamically
+ *                              if true
+ *
+ * %SKL_TKN_U8_IN_QUEUE_COUNT:  Store the number of Input pins
+ *
+ * %SKL_TKN_U8_OUT_QUEUE_COUNT: Store the number of Output pins
+ *
+ * %SKL_TKN_U8_TIME_SLOT:       TDM slot number
+ *
+ * %SKL_TKN_U8_CORE_ID:         Stores module affinity value.Can take
+ *                              the values:
+ *                              SKL_AFFINITY_CORE_0 = 0,
+ *                              SKL_AFFINITY_CORE_1,
+ *                              SKL_AFFINITY_CORE_MAX
+ *
+ * %SKL_TKN_U8_MOD_TYPE:        Module type value.
+ *
+ * %SKL_TKN_U8_CONN_TYPE:       Module connection type can be a FE,
+ *                              BE or NONE as defined :
+ *                              SKL_PIPE_CONN_TYPE_NONE = 0,
+ *                              SKL_PIPE_CONN_TYPE_FE = 1 (HOST_DMA)
+ *                              SKL_PIPE_CONN_TYPE_BE = 2 (LINK_DMA)
+ *
+ * %SKL_TKN_U8_DEV_TYPE:        Type of device to which the module is
+ *                              connected
+ *                              Can take the values:
+ *                              SKL_DEVICE_BT = 0x0,
+ *                              SKL_DEVICE_DMIC = 0x1,
+ *                              SKL_DEVICE_I2S = 0x2,
+ *                              SKL_DEVICE_SLIMBUS = 0x3,
+ *                              SKL_DEVICE_HDALINK = 0x4,
+ *                              SKL_DEVICE_HDAHOST = 0x5,
+ *                              SKL_DEVICE_NONE
+ *
+ * %SKL_TKN_U8_HW_CONN_TYPE:    Connection type of the HW to which the
+ *                              module is connected
+ *                              SKL_CONN_NONE = 0,
+ *                              SKL_CONN_SOURCE = 1,
+ *                              SKL_CONN_SINK = 2
+ *
+ * %SKL_TKN_U16_PIN_INST_ID:    Stores the pin instance id
+ *
+ * %SKL_TKN_U16_MOD_INST_ID:    Stores the mdule instance id
+ *
+ * %SKL_TKN_U32_MAX_MCPS:       Module max mcps value
+ *
+ * %SKL_TKN_U32_MEM_PAGES:      Module resource pages
+ *
+ * %SKL_TKN_U32_OBS:            Stores Output Buffer size
+ *
+ * %SKL_TKN_U32_IBS:            Stores input buffer size
+ *
+ * %SKL_TKN_U32_VBUS_ID:        Module VBUS_ID. PDM=0, SSP0=0,
+ *                              SSP1=1,SSP2=2,
+ *                              SSP3=3, SSP4=4,
+ *                              SSP5=5, SSP6=6,INVALID
+ *
+ * %SKL_TKN_U32_PARAMS_FIXUP:   Module Params fixup mask
+ * %SKL_TKN_U32_CONVERTER:      Module params converter mask
+ * %SKL_TKN_U32_PIPE_ID:        Stores the pipe id
+ *
+ * %SKL_TKN_U32_PIPE_CONN_TYPE: Type of the token to which the pipe is
+ *                              connected to. It can be
+ *                              SKL_PIPE_CONN_TYPE_NONE = 0,
+ *                              SKL_PIPE_CONN_TYPE_FE = 1 (HOST_DMA),
+ *                              SKL_PIPE_CONN_TYPE_BE = 2 (LINK_DMA),
+ *
+ * %SKL_TKN_U32_PIPE_PRIORITY:  Pipe priority value
+ * %SKL_TKN_U32_PIPE_MEM_PGS:   Pipe resource pages
+ *
+ * %SKL_TKN_U32_DIR_PIN_COUNT:  Value for the direction to set input/output
+ *                              formats and the pin count.
+ *                              The first 4 bits have the direction
+ *                              value and the next 4 have
+ *                              the pin count value.
+ *                              SKL_DIR_IN = 0, SKL_DIR_OUT = 1.
+ *                              The input and output formats
+ *                              share the same set of tokens
+ *                              with the distinction between input
+ *                              and output made by reading direction
+ *                              token.
+ *
+ * %SKL_TKN_U32_FMT_CH:         Supported channel count
+ *
+ * %SKL_TKN_U32_FMT_FREQ:       Supported frequency/sample rate
+ *
+ * %SKL_TKN_U32_FMT_BIT_DEPTH:  Supported container size
+ *
+ * %SKL_TKN_U32_FMT_SAMPLE_SIZE:Number of samples in the container
+ *
+ * %SKL_TKN_U32_FMT_CH_CONFIG:  Supported channel configurations for the
+ *                              input/output.
+ *
+ * %SKL_TKN_U32_FMT_INTERLEAVE: Interleaving style which can be per
+ *                              channel or per sample. The values can be :
+ *                              SKL_INTERLEAVING_PER_CHANNEL = 0,
+ *                              SKL_INTERLEAVING_PER_SAMPLE = 1,
+ *
+ * %SKL_TKN_U32_FMT_SAMPLE_TYPE:
+ *                              Specifies the sample type. Can take the
+ *                              values: SKL_SAMPLE_TYPE_INT_MSB = 0,
+ *                              SKL_SAMPLE_TYPE_INT_LSB = 1,
+ *                              SKL_SAMPLE_TYPE_INT_SIGNED = 2,
+ *                              SKL_SAMPLE_TYPE_INT_UNSIGNED = 3,
+ *                              SKL_SAMPLE_TYPE_FLOAT = 4
+ *
+ * %SKL_TKN_U32_CH_MAP:         Channel map values
+ * %SKL_TKN_U32_MOD_SET_PARAMS: It can take these values:
+ *                              SKL_PARAM_DEFAULT, SKL_PARAM_INIT,
+ *                              SKL_PARAM_SET, SKL_PARAM_BIND
+ *
+ * %SKL_TKN_U32_MOD_PARAM_ID:   ID of the module params
+ *
+ * %SKL_TKN_U32_CAPS_SET_PARAMS:
+ *                              Set params value
+ *
+ * %SKL_TKN_U32_CAPS_PARAMS_ID: Params ID
+ *
+ * %SKL_TKN_U32_CAPS_SIZE:      Caps size
+ *
+ * %SKL_TKN_U32_PROC_DOMAIN:    Specify processing domain
+ *
+ * module_id and loadable flags dont have tokens as these values will be
+ * read from the DSP FW manifest
+ */
+enum SKL_TKNS {
+	SKL_TKN_UUID = 1,
+	SKL_TKN_U8_NUM_BLOCKS,
+	SKL_TKN_U8_BLOCK_TYPE,
+	SKL_TKN_U8_IN_PIN_TYPE,
+	SKL_TKN_U8_OUT_PIN_TYPE,
+	SKL_TKN_U8_DYN_IN_PIN,
+	SKL_TKN_U8_DYN_OUT_PIN,
+	SKL_TKN_U8_IN_QUEUE_COUNT,
+	SKL_TKN_U8_OUT_QUEUE_COUNT,
+	SKL_TKN_U8_TIME_SLOT,
+	SKL_TKN_U8_CORE_ID,
+	SKL_TKN_U8_MOD_TYPE,
+	SKL_TKN_U8_CONN_TYPE,
+	SKL_TKN_U8_DEV_TYPE,
+	SKL_TKN_U8_HW_CONN_TYPE,
+	SKL_TKN_U16_MOD_INST_ID,
+	SKL_TKN_U16_BLOCK_SIZE,
+	SKL_TKN_U32_MAX_MCPS,
+	SKL_TKN_U32_MEM_PAGES,
+	SKL_TKN_U32_OBS,
+	SKL_TKN_U32_IBS,
+	SKL_TKN_U32_VBUS_ID,
+	SKL_TKN_U32_PARAMS_FIXUP,
+	SKL_TKN_U32_CONVERTER,
+	SKL_TKN_U32_PIPE_ID,
+	SKL_TKN_U32_PIPE_CONN_TYPE,
+	SKL_TKN_U32_PIPE_PRIORITY,
+	SKL_TKN_U32_PIPE_MEM_PGS,
+	SKL_TKN_U32_DIR_PIN_COUNT,
+	SKL_TKN_U32_FMT_CH,
+	SKL_TKN_U32_FMT_FREQ,
+	SKL_TKN_U32_FMT_BIT_DEPTH,
+	SKL_TKN_U32_FMT_SAMPLE_SIZE,
+	SKL_TKN_U32_FMT_CH_CONFIG,
+	SKL_TKN_U32_FMT_INTERLEAVE,
+	SKL_TKN_U32_FMT_SAMPLE_TYPE,
+	SKL_TKN_U32_FMT_CH_MAP,
+	SKL_TKN_U32_PIN_MOD_ID,
+	SKL_TKN_U32_PIN_INST_ID,
+	SKL_TKN_U32_MOD_SET_PARAMS,
+	SKL_TKN_U32_MOD_PARAM_ID,
+	SKL_TKN_U32_CAPS_SET_PARAMS,
+	SKL_TKN_U32_CAPS_PARAMS_ID,
+	SKL_TKN_U32_CAPS_SIZE,
+	SKL_TKN_U32_PROC_DOMAIN,
+	SKL_TKN_MAX = SKL_TKN_U32_PROC_DOMAIN,
+};
+
+#endif
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 2/4] ASoC: Intel: Skylake: Parse vendor tokens to build module data
  2016-08-12  6:59 [PATCH 0/4] ASoC: Intel: Skylake: Add token support for topology data Vinod Koul
  2016-08-12  6:59 ` [PATCH 1/4] ASoC: uapi: Intel: Skylake: Define vendor specific tokens Vinod Koul
@ 2016-08-12  6:59 ` Vinod Koul
  2016-08-22 17:59   ` Applied "ASoC: Intel: Skylake: Parse vendor tokens to build module data" to the asoc tree Mark Brown
  2016-08-12  6:59 ` [PATCH 3/4] ASoC: Intel: Skylake: Remove dfw config and associated structures Vinod Koul
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 15+ messages in thread
From: Vinod Koul @ 2016-08-12  6:59 UTC (permalink / raw)
  To: alsa-devel
  Cc: liam.r.girdwood, patches.audio, broonie, Vinod Koul, Shreyas NC

From: Shreyas NC <shreyas.nc@intel.com>

Skl topology data is preceded by a descriptor for number of data
blocks, the size of the data block and type of data block. The
type of the data block can be either a tuple or a binary blob.

Private data is parsed based on data block type and module data
is filled accordingly.

Signed-off-by: Shreyas NC <shreyas.nc@intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
---
 sound/soc/intel/skylake/skl-topology.c       | 645 ++++++++++++++++++++++-----
 sound/soc/intel/skylake/skl-tplg-interface.h |  10 +
 2 files changed, 545 insertions(+), 110 deletions(-)

diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c
index 07efbb7f18c4..df58691d0b3c 100644
--- a/sound/soc/intel/skylake/skl-topology.c
+++ b/sound/soc/intel/skylake/skl-topology.c
@@ -21,6 +21,7 @@
 #include <linux/firmware.h>
 #include <sound/soc.h>
 #include <sound/soc-topology.h>
+#include <uapi/sound/snd_sst_tokens.h>
 #include "skl-sst-dsp.h"
 #include "skl-sst-ipc.h"
 #include "skl-topology.h"
@@ -32,6 +33,8 @@
 #define SKL_CH_FIXUP_MASK		(1 << 0)
 #define SKL_RATE_FIXUP_MASK		(1 << 1)
 #define SKL_FMT_FIXUP_MASK		(1 << 2)
+#define SKL_IN_DIR_BIT_MASK		BIT(0)
+#define SKL_PIN_COUNT_MASK		GENMASK(7, 4)
 
 /*
  * SKL DSP driver modelling uses only few DAPM widgets so for rest we will
@@ -1468,85 +1471,570 @@ static const struct snd_soc_tplg_bytes_ext_ops skl_tlv_ops[] = {
 					skl_tplg_tlv_control_set},
 };
 
-/*
- * The topology binary passes the pin info for a module so initialize the pin
- * info passed into module instance
- */
-static void skl_fill_module_pin_info(struct skl_dfw_module_pin *dfw_pin,
-						struct skl_module_pin *m_pin,
-						bool is_dynamic, int max_pin)
+static int skl_tplg_fill_pipe_tkn(struct device *dev,
+			struct skl_pipe *pipe, u32 tkn,
+			u32 tkn_val)
 {
-	int i;
 
-	for (i = 0; i < max_pin; i++) {
-		m_pin[i].id.module_id = dfw_pin[i].module_id;
-		m_pin[i].id.instance_id = dfw_pin[i].instance_id;
-		m_pin[i].in_use = false;
-		m_pin[i].is_dynamic = is_dynamic;
-		m_pin[i].pin_state = SKL_PIN_UNBIND;
+	switch (tkn) {
+	case SKL_TKN_U32_PIPE_CONN_TYPE:
+		pipe->conn_type = tkn_val;
+		break;
+
+	case SKL_TKN_U32_PIPE_PRIORITY:
+		pipe->pipe_priority = tkn_val;
+		break;
+
+	case SKL_TKN_U32_PIPE_MEM_PGS:
+		pipe->memory_pages = tkn_val;
+		break;
+
+	default:
+		dev_err(dev, "Token not handled %d\n", tkn);
+		return -EINVAL;
 	}
+
+	return 0;
 }
 
 /*
- * Add pipeline from topology binary into driver pipeline list
- *
- * If already added we return that instance
- * Otherwise we create a new instance and add into driver list
+ * Add pipeline by parsing the relevant tokens
+ * Return an existing pipe if the pipe already exists.
  */
-static struct skl_pipe *skl_tplg_add_pipe(struct device *dev,
-			struct skl *skl, struct skl_dfw_pipe *dfw_pipe)
+static int skl_tplg_add_pipe(struct device *dev,
+		struct skl_module_cfg *mconfig, struct skl *skl,
+		struct snd_soc_tplg_vendor_value_elem *tkn_elem)
 {
 	struct skl_pipeline *ppl;
 	struct skl_pipe *pipe;
 	struct skl_pipe_params *params;
 
 	list_for_each_entry(ppl, &skl->ppl_list, node) {
-		if (ppl->pipe->ppl_id == dfw_pipe->pipe_id)
-			return ppl->pipe;
+		if (ppl->pipe->ppl_id == tkn_elem->value) {
+			mconfig->pipe = ppl->pipe;
+			return EEXIST;
+		}
 	}
 
 	ppl = devm_kzalloc(dev, sizeof(*ppl), GFP_KERNEL);
 	if (!ppl)
-		return NULL;
+		return -ENOMEM;
 
 	pipe = devm_kzalloc(dev, sizeof(*pipe), GFP_KERNEL);
 	if (!pipe)
-		return NULL;
+		return -ENOMEM;
 
 	params = devm_kzalloc(dev, sizeof(*params), GFP_KERNEL);
 	if (!params)
-		return NULL;
+		return -ENOMEM;
 
-	pipe->ppl_id = dfw_pipe->pipe_id;
-	pipe->memory_pages = dfw_pipe->memory_pages;
-	pipe->pipe_priority = dfw_pipe->pipe_priority;
-	pipe->conn_type = dfw_pipe->conn_type;
-	pipe->state = SKL_PIPE_INVALID;
 	pipe->p_params = params;
+	pipe->ppl_id = tkn_elem->value;
 	INIT_LIST_HEAD(&pipe->w_list);
 
 	ppl->pipe = pipe;
 	list_add(&ppl->node, &skl->ppl_list);
 
-	return ppl->pipe;
+	mconfig->pipe = pipe;
+	mconfig->pipe->state = SKL_PIPE_INVALID;
+
+	return 0;
+}
+
+static int skl_tplg_fill_pin(struct device *dev, u32 tkn,
+			struct skl_module_pin *m_pin,
+			int pin_index, u32 value)
+{
+	switch (tkn) {
+	case SKL_TKN_U32_PIN_MOD_ID:
+		m_pin[pin_index].id.module_id = value;
+		break;
+
+	case SKL_TKN_U32_PIN_INST_ID:
+		m_pin[pin_index].id.instance_id = value;
+		break;
+
+	default:
+		dev_err(dev, "%d Not a pin token\n", value);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/*
+ * Parse for pin config specific tokens to fill up the
+ * module private data
+ */
+static int skl_tplg_fill_pins_info(struct device *dev,
+		struct skl_module_cfg *mconfig,
+		struct snd_soc_tplg_vendor_value_elem *tkn_elem,
+		int dir, int pin_count)
+{
+	int ret;
+	struct skl_module_pin *m_pin;
+
+	switch (dir) {
+	case SKL_DIR_IN:
+		m_pin = mconfig->m_in_pin;
+		break;
+
+	case SKL_DIR_OUT:
+		m_pin = mconfig->m_out_pin;
+		break;
+
+	default:
+		dev_err(dev, "Invalid direction value");
+		return -EINVAL;
+	}
+
+	ret = skl_tplg_fill_pin(dev, tkn_elem->token,
+			m_pin, pin_count, tkn_elem->value);
+
+	if (ret < 0)
+		return ret;
+
+	m_pin[pin_count].in_use = false;
+	m_pin[pin_count].pin_state = SKL_PIN_UNBIND;
+
+	return 0;
 }
 
-static void skl_tplg_fill_fmt(struct skl_module_fmt *dst_fmt,
-				struct skl_dfw_module_fmt *src_fmt,
-				int pins)
+/*
+ * Fill up input/output module config format based
+ * on the direction
+ */
+static int skl_tplg_fill_fmt(struct device *dev,
+		struct skl_module_cfg *mconfig,	u32 tkn,
+		u32 value, u32 dir, u32 pin_count)
+{
+	struct skl_module_fmt *dst_fmt;
+
+	switch (dir) {
+	case SKL_DIR_IN:
+		dst_fmt = mconfig->in_fmt;
+		dst_fmt += pin_count;
+		break;
+
+	case SKL_DIR_OUT:
+		dst_fmt = mconfig->out_fmt;
+		dst_fmt += pin_count;
+		break;
+
+	default:
+		dev_err(dev, "Invalid direction value");
+		return -EINVAL;
+	}
+
+	switch (tkn) {
+	case SKL_TKN_U32_FMT_CH:
+		dst_fmt->channels  = value;
+		break;
+
+	case SKL_TKN_U32_FMT_FREQ:
+		dst_fmt->s_freq = value;
+		break;
+
+	case SKL_TKN_U32_FMT_BIT_DEPTH:
+		dst_fmt->bit_depth = value;
+		break;
+
+	case SKL_TKN_U32_FMT_SAMPLE_SIZE:
+		dst_fmt->valid_bit_depth = value;
+		break;
+
+	case SKL_TKN_U32_FMT_CH_CONFIG:
+		dst_fmt->ch_cfg = value;
+		break;
+
+	case SKL_TKN_U32_FMT_INTERLEAVE:
+		dst_fmt->interleaving_style = value;
+		break;
+
+	case SKL_TKN_U32_FMT_SAMPLE_TYPE:
+		dst_fmt->sample_type = value;
+		break;
+
+	case SKL_TKN_U32_FMT_CH_MAP:
+		dst_fmt->ch_map = value;
+		break;
+
+	default:
+		dev_err(dev, "Invalid token %d", tkn);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int skl_tplg_get_uuid(struct device *dev, struct skl_module_cfg *mconfig,
+	      struct snd_soc_tplg_vendor_uuid_elem *uuid_tkn)
+{
+	if (uuid_tkn->token == SKL_TKN_UUID)
+		memcpy(&mconfig->guid, &uuid_tkn->uuid, 16);
+	else {
+		dev_err(dev, "Not an UUID token tkn %d", uuid_tkn->token);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void skl_tplg_fill_pin_dynamic_val(
+		struct skl_module_pin *mpin, u32 pin_count, u32 value)
 {
 	int i;
 
-	for (i = 0; i < pins; i++) {
-		dst_fmt[i].channels  = src_fmt[i].channels;
-		dst_fmt[i].s_freq = src_fmt[i].freq;
-		dst_fmt[i].bit_depth = src_fmt[i].bit_depth;
-		dst_fmt[i].valid_bit_depth = src_fmt[i].valid_bit_depth;
-		dst_fmt[i].ch_cfg = src_fmt[i].ch_cfg;
-		dst_fmt[i].ch_map = src_fmt[i].ch_map;
-		dst_fmt[i].interleaving_style = src_fmt[i].interleaving_style;
-		dst_fmt[i].sample_type = src_fmt[i].sample_type;
+	for (i = 0; i < pin_count; i++)
+		mpin[i].is_dynamic = value;
+}
+
+/*
+ * Parse tokens to fill up the module private data
+ */
+static int skl_tplg_get_token(struct device *dev,
+		struct snd_soc_tplg_vendor_value_elem *tkn_elem,
+		struct skl *skl, struct skl_module_cfg *mconfig)
+{
+	int tkn_count = 0;
+	int ret;
+	static int is_pipe_exists;
+	static int pin_index, dir;
+
+	if (tkn_elem->token > SKL_TKN_MAX)
+		return -EINVAL;
+
+	switch (tkn_elem->token) {
+	case SKL_TKN_U8_IN_QUEUE_COUNT:
+		mconfig->max_in_queue = tkn_elem->value;
+		mconfig->m_in_pin = devm_kzalloc(dev, mconfig->max_in_queue *
+					sizeof(*mconfig->m_in_pin),
+					GFP_KERNEL);
+		if (!mconfig->m_in_pin)
+			return -ENOMEM;
+
+		break;
+
+	case SKL_TKN_U8_OUT_QUEUE_COUNT:
+		mconfig->max_out_queue = tkn_elem->value;
+		mconfig->m_out_pin = devm_kzalloc(dev, mconfig->max_out_queue *
+					sizeof(*mconfig->m_out_pin),
+					GFP_KERNEL);
+
+		if (!mconfig->m_out_pin)
+			return -ENOMEM;
+
+		break;
+
+	case SKL_TKN_U8_DYN_IN_PIN:
+		if (!mconfig->m_in_pin)
+			return -ENOMEM;
+
+		skl_tplg_fill_pin_dynamic_val(mconfig->m_in_pin,
+			mconfig->max_in_queue, tkn_elem->value);
+
+		break;
+
+	case SKL_TKN_U8_DYN_OUT_PIN:
+		if (!mconfig->m_out_pin)
+			return -ENOMEM;
+
+		skl_tplg_fill_pin_dynamic_val(mconfig->m_out_pin,
+			mconfig->max_out_queue, tkn_elem->value);
+
+		break;
+
+	case SKL_TKN_U8_TIME_SLOT:
+		mconfig->time_slot = tkn_elem->value;
+		break;
+
+	case SKL_TKN_U8_CORE_ID:
+		mconfig->core_id = tkn_elem->value;
+
+	case SKL_TKN_U8_MOD_TYPE:
+		mconfig->m_type = tkn_elem->value;
+		break;
+
+	case SKL_TKN_U8_DEV_TYPE:
+		mconfig->dev_type = tkn_elem->value;
+		break;
+
+	case SKL_TKN_U8_HW_CONN_TYPE:
+		mconfig->hw_conn_type = tkn_elem->value;
+		break;
+
+	case SKL_TKN_U16_MOD_INST_ID:
+		mconfig->id.instance_id =
+		tkn_elem->value;
+		break;
+
+	case SKL_TKN_U32_MEM_PAGES:
+		mconfig->mem_pages = tkn_elem->value;
+		break;
+
+	case SKL_TKN_U32_MAX_MCPS:
+		mconfig->mcps = tkn_elem->value;
+		break;
+
+	case SKL_TKN_U32_OBS:
+		mconfig->obs = tkn_elem->value;
+		break;
+
+	case SKL_TKN_U32_IBS:
+		mconfig->ibs = tkn_elem->value;
+		break;
+
+	case SKL_TKN_U32_VBUS_ID:
+		mconfig->vbus_id = tkn_elem->value;
+		break;
+
+	case SKL_TKN_U32_PARAMS_FIXUP:
+		mconfig->params_fixup = tkn_elem->value;
+		break;
+
+	case SKL_TKN_U32_CONVERTER:
+		mconfig->converter = tkn_elem->value;
+		break;
+
+	case SKL_TKN_U32_PIPE_ID:
+		ret = skl_tplg_add_pipe(dev,
+				mconfig, skl, tkn_elem);
+
+		if (ret < 0)
+			return is_pipe_exists;
+
+		if (ret == EEXIST)
+			is_pipe_exists = 1;
+
+		break;
+
+	case SKL_TKN_U32_PIPE_CONN_TYPE:
+	case SKL_TKN_U32_PIPE_PRIORITY:
+	case SKL_TKN_U32_PIPE_MEM_PGS:
+		if (is_pipe_exists) {
+			ret = skl_tplg_fill_pipe_tkn(dev, mconfig->pipe,
+					tkn_elem->token, tkn_elem->value);
+			if (ret < 0)
+				return ret;
+		}
+
+		break;
+
+	/*
+	 * SKL_TKN_U32_DIR_PIN_COUNT token has the value for both
+	 * direction and the pin count. The first four bits represent
+	 * direction and next four the pin count.
+	 */
+	case SKL_TKN_U32_DIR_PIN_COUNT:
+		dir = tkn_elem->value & SKL_IN_DIR_BIT_MASK;
+		pin_index = (tkn_elem->value &
+			SKL_PIN_COUNT_MASK) >> 4;
+
+		break;
+
+	case SKL_TKN_U32_FMT_CH:
+	case SKL_TKN_U32_FMT_FREQ:
+	case SKL_TKN_U32_FMT_BIT_DEPTH:
+	case SKL_TKN_U32_FMT_SAMPLE_SIZE:
+	case SKL_TKN_U32_FMT_CH_CONFIG:
+	case SKL_TKN_U32_FMT_INTERLEAVE:
+	case SKL_TKN_U32_FMT_SAMPLE_TYPE:
+	case SKL_TKN_U32_FMT_CH_MAP:
+		ret = skl_tplg_fill_fmt(dev, mconfig, tkn_elem->token,
+				tkn_elem->value, dir, pin_index);
+
+		if (ret < 0)
+			return ret;
+
+		break;
+
+	case SKL_TKN_U32_PIN_MOD_ID:
+	case SKL_TKN_U32_PIN_INST_ID:
+		ret = skl_tplg_fill_pins_info(dev,
+				mconfig, tkn_elem, dir,
+				pin_index);
+		if (ret < 0)
+			return ret;
+
+		break;
+
+	case SKL_TKN_U32_CAPS_SIZE:
+		mconfig->formats_config.caps_size =
+			tkn_elem->value;
+
+		break;
+
+	case SKL_TKN_U32_PROC_DOMAIN:
+		mconfig->domain =
+			tkn_elem->value;
+
+		break;
+
+	case SKL_TKN_U8_IN_PIN_TYPE:
+	case SKL_TKN_U8_OUT_PIN_TYPE:
+	case SKL_TKN_U8_CONN_TYPE:
+		break;
+
+	default:
+		dev_err(dev, "Token %d not handled\n",
+				tkn_elem->token);
+		return -EINVAL;
 	}
+
+	tkn_count++;
+
+	return tkn_count;
+}
+
+/*
+ * Parse the vendor array for specific tokens to construct
+ * module private data
+ */
+static int skl_tplg_get_tokens(struct device *dev,
+		char *pvt_data,	struct skl *skl,
+		struct skl_module_cfg *mconfig, int block_size)
+{
+	struct snd_soc_tplg_vendor_array *array;
+	struct snd_soc_tplg_vendor_value_elem *tkn_elem;
+	int tkn_count = 0, ret;
+	int off = 0, tuple_size = 0;
+
+	if (block_size <= 0)
+		return -EINVAL;
+
+	while (tuple_size < block_size) {
+		array = (struct snd_soc_tplg_vendor_array *)(pvt_data + off);
+
+		off += array->size;
+
+		switch (array->type) {
+		case SND_SOC_TPLG_TUPLE_TYPE_STRING:
+			dev_warn(dev, "no string tokens expected for skl tplg");
+			continue;
+
+		case SND_SOC_TPLG_TUPLE_TYPE_UUID:
+			ret = skl_tplg_get_uuid(dev, mconfig, array->uuid);
+			if (ret < 0)
+				return ret;
+
+			tuple_size += sizeof(*array->uuid);
+
+			continue;
+
+		default:
+			tkn_elem = array->value;
+			tkn_count = 0;
+			break;
+		}
+
+		while (tkn_count <= (array->num_elems - 1)) {
+			ret = skl_tplg_get_token(dev, tkn_elem,
+					skl, mconfig);
+
+			if (ret < 0)
+				return ret;
+
+			tkn_count = tkn_count + ret;
+			tkn_elem++;
+		}
+
+		tuple_size += tkn_count * sizeof(*tkn_elem);
+	}
+
+	return 0;
+}
+
+/*
+ * Every data block is preceded by a descriptor to read the number
+ * of data blocks, they type of the block and it's size
+ */
+static int skl_tplg_get_desc_blocks(struct device *dev,
+		struct snd_soc_tplg_vendor_array *array)
+{
+	struct snd_soc_tplg_vendor_value_elem *tkn_elem;
+
+	tkn_elem = array->value;
+
+	switch (tkn_elem->token) {
+	case SKL_TKN_U8_NUM_BLOCKS:
+	case SKL_TKN_U8_BLOCK_TYPE:
+	case SKL_TKN_U16_BLOCK_SIZE:
+		return tkn_elem->value;
+
+	default:
+		dev_err(dev, "Invalid descriptor token %d", tkn_elem->token);
+		break;
+	}
+
+	return -EINVAL;
+}
+
+/*
+ * Parse the private data for the token and corresponding value.
+ * The private data can have multiple data blocks. So, a data block
+ * is preceded by a descriptor for number of blocks and a descriptor
+ * for the type and size of the suceeding data block.
+ */
+static int skl_tplg_get_pvt_data(struct snd_soc_tplg_dapm_widget *tplg_w,
+				struct skl *skl, struct device *dev,
+				struct skl_module_cfg *mconfig)
+{
+	struct snd_soc_tplg_vendor_array *array;
+	int num_blocks, block_size = 0, block_type, off = 0;
+	char *data;
+	int ret;
+
+	/* Read the NUM_DATA_BLOCKS descriptor */
+	array = (struct snd_soc_tplg_vendor_array *)tplg_w->priv.data;
+	ret = skl_tplg_get_desc_blocks(dev, array);
+	if (ret < 0)
+		return ret;
+	num_blocks = ret;
+
+	off += array->size;
+	array = (struct snd_soc_tplg_vendor_array *)(tplg_w->priv.data + off);
+
+	/* Read the BLOCK_TYPE and BLOCK_SIZE descriptor */
+	while (num_blocks > 0) {
+		ret = skl_tplg_get_desc_blocks(dev, array);
+
+		if (ret < 0)
+			return ret;
+		block_type = ret;
+		off += array->size;
+
+		array = (struct snd_soc_tplg_vendor_array *)
+			(tplg_w->priv.data + off);
+
+		ret = skl_tplg_get_desc_blocks(dev, array);
+
+		if (ret < 0)
+			return ret;
+		block_size = ret;
+		off += array->size;
+
+		array = (struct snd_soc_tplg_vendor_array *)
+			(tplg_w->priv.data + off);
+
+		data = (tplg_w->priv.data + off);
+
+		if (block_type == SKL_TYPE_TUPLE) {
+			ret = skl_tplg_get_tokens(dev, data,
+					skl, mconfig, block_size);
+
+			if (ret < 0)
+				return ret;
+
+			--num_blocks;
+		} else {
+			if (mconfig->formats_config.caps_size > 0)
+				memcpy(mconfig->formats_config.caps, data,
+					mconfig->formats_config.caps_size);
+			--num_blocks;
+		}
+	}
+
+	return 0;
 }
 
 static void skl_clear_pin_config(struct snd_soc_platform *platform,
@@ -1614,9 +2102,6 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt,
 	struct skl *skl = ebus_to_skl(ebus);
 	struct hdac_bus *bus = ebus_to_hbus(ebus);
 	struct skl_module_cfg *mconfig;
-	struct skl_pipe *pipe;
-	struct skl_dfw_module *dfw_config =
-				(struct skl_dfw_module *)tplg_w->priv.data;
 
 	if (!tplg_w->priv.size)
 		goto bind_event;
@@ -1627,77 +2112,17 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt,
 		return -ENOMEM;
 
 	w->priv = mconfig;
-	memcpy(&mconfig->guid, &dfw_config->uuid, 16);
 
 	/*
 	 * module binary can be loaded later, so set it to query when
 	 * module is load for a use case
 	 */
 	mconfig->id.module_id = -1;
-	mconfig->id.instance_id = dfw_config->instance_id;
-	mconfig->mcps = dfw_config->max_mcps;
-	mconfig->ibs = dfw_config->ibs;
-	mconfig->obs = dfw_config->obs;
-	mconfig->core_id = dfw_config->core_id;
-	mconfig->max_in_queue = dfw_config->max_in_queue;
-	mconfig->max_out_queue = dfw_config->max_out_queue;
-	mconfig->is_loadable = dfw_config->is_loadable;
-	mconfig->domain = dfw_config->proc_domain;
-	skl_tplg_fill_fmt(mconfig->in_fmt, dfw_config->in_fmt,
-						MODULE_MAX_IN_PINS);
-	skl_tplg_fill_fmt(mconfig->out_fmt, dfw_config->out_fmt,
-						MODULE_MAX_OUT_PINS);
-
-	mconfig->params_fixup = dfw_config->params_fixup;
-	mconfig->converter = dfw_config->converter;
-	mconfig->m_type = dfw_config->module_type;
-	mconfig->vbus_id = dfw_config->vbus_id;
-	mconfig->mem_pages = dfw_config->mem_pages;
-
-	pipe = skl_tplg_add_pipe(bus->dev, skl, &dfw_config->pipe);
-	if (pipe)
-		mconfig->pipe = pipe;
-
-	mconfig->dev_type = dfw_config->dev_type;
-	mconfig->hw_conn_type = dfw_config->hw_conn_type;
-	mconfig->time_slot = dfw_config->time_slot;
-	mconfig->formats_config.caps_size = dfw_config->caps.caps_size;
-
-	mconfig->m_in_pin = devm_kzalloc(bus->dev, (mconfig->max_in_queue) *
-						sizeof(*mconfig->m_in_pin),
-						GFP_KERNEL);
-	if (!mconfig->m_in_pin)
-		return -ENOMEM;
-
-	mconfig->m_out_pin = devm_kzalloc(bus->dev, (mconfig->max_out_queue) *
-						sizeof(*mconfig->m_out_pin),
-						GFP_KERNEL);
-	if (!mconfig->m_out_pin)
-		return -ENOMEM;
-
-	skl_fill_module_pin_info(dfw_config->in_pin, mconfig->m_in_pin,
-						dfw_config->is_dynamic_in_pin,
-						mconfig->max_in_queue);
-
-	skl_fill_module_pin_info(dfw_config->out_pin, mconfig->m_out_pin,
-						 dfw_config->is_dynamic_out_pin,
-							mconfig->max_out_queue);
-
-
-	if (mconfig->formats_config.caps_size == 0)
-		goto bind_event;
-
-	mconfig->formats_config.caps = (u32 *)devm_kzalloc(bus->dev,
-			mconfig->formats_config.caps_size, GFP_KERNEL);
-
-	if (mconfig->formats_config.caps == NULL)
-		return -ENOMEM;
-
-	memcpy(mconfig->formats_config.caps, dfw_config->caps.caps,
-						 dfw_config->caps.caps_size);
-	mconfig->formats_config.param_id = dfw_config->caps.param_id;
-	mconfig->formats_config.set_params = dfw_config->caps.set_params;
 
+	/* Parse private data for tuples */
+	ret = skl_tplg_get_pvt_data(tplg_w, skl, bus->dev, mconfig);
+	if (ret < 0)
+		return ret;
 bind_event:
 	if (tplg_w->event_type == 0) {
 		dev_dbg(bus->dev, "ASoC: No event handler required\n");
diff --git a/sound/soc/intel/skylake/skl-tplg-interface.h b/sound/soc/intel/skylake/skl-tplg-interface.h
index bd8b4ae43557..281762eca0ab 100644
--- a/sound/soc/intel/skylake/skl-tplg-interface.h
+++ b/sound/soc/intel/skylake/skl-tplg-interface.h
@@ -241,4 +241,14 @@ struct skl_dfw_manifest {
 	struct lib_info lib[HDA_MAX_LIB];
 } __packed;
 
+enum skl_tkn_dir {
+	SKL_DIR_IN,
+	SKL_DIR_OUT
+};
+
+enum skl_tuple_type {
+	SKL_TYPE_TUPLE,
+	SKL_TYPE_DATA
+};
+
 #endif
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 3/4] ASoC: Intel: Skylake: Remove dfw config and associated structures
  2016-08-12  6:59 [PATCH 0/4] ASoC: Intel: Skylake: Add token support for topology data Vinod Koul
  2016-08-12  6:59 ` [PATCH 1/4] ASoC: uapi: Intel: Skylake: Define vendor specific tokens Vinod Koul
  2016-08-12  6:59 ` [PATCH 2/4] ASoC: Intel: Skylake: Parse vendor tokens to build module data Vinod Koul
@ 2016-08-12  6:59 ` Vinod Koul
  2016-08-22 17:59   ` Applied "ASoC: Intel: Skylake: Remove dfw config and associated structures" to the asoc tree Mark Brown
  2016-08-12  6:59 ` [PATCH 4/4] ASoC: Intel: Skylake: Parse manifest data Vinod Koul
  2016-08-12 10:41 ` [PATCH 0/4] ASoC: Intel: Skylake: Add token support for topology data Mark Brown
  4 siblings, 1 reply; 15+ messages in thread
From: Vinod Koul @ 2016-08-12  6:59 UTC (permalink / raw)
  To: alsa-devel
  Cc: liam.r.girdwood, patches.audio, broonie, Vinod Koul, Shreyas NC

From: Shreyas NC <shreyas.nc@intel.com>

The skl_dfw_config structure is no longer required as the module
config is populated by parsing and reading the token values.

So, remove the structure.

Signed-off-by: Shreyas NC <shreyas.nc@intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
---
 sound/soc/intel/skylake/skl-sst-utils.c      |  5 --
 sound/soc/intel/skylake/skl-tplg-interface.h | 73 ----------------------------
 2 files changed, 78 deletions(-)

diff --git a/sound/soc/intel/skylake/skl-sst-utils.c b/sound/soc/intel/skylake/skl-sst-utils.c
index 0f990ebbe620..3a508b7a0041 100644
--- a/sound/soc/intel/skylake/skl-sst-utils.c
+++ b/sound/soc/intel/skylake/skl-sst-utils.c
@@ -28,11 +28,6 @@
 /* FW Extended Manifest Header id = $AE1 */
 #define SKL_EXT_MANIFEST_HEADER_MAGIC   0x31454124
 
-struct skl_dfw_module_mod {
-	char name[100];
-	struct skl_dfw_module skl_dfw_mod;
-};
-
 struct UUID {
 	u8 id[16];
 };
diff --git a/sound/soc/intel/skylake/skl-tplg-interface.h b/sound/soc/intel/skylake/skl-tplg-interface.h
index 281762eca0ab..e208724f9db3 100644
--- a/sound/soc/intel/skylake/skl-tplg-interface.h
+++ b/sound/soc/intel/skylake/skl-tplg-interface.h
@@ -148,79 +148,6 @@ enum skl_module_param_type {
 	SKL_PARAM_BIND
 };
 
-struct skl_dfw_module_pin {
-	u16 module_id;
-	u16 instance_id;
-} __packed;
-
-struct skl_dfw_module_fmt {
-	u32 channels;
-	u32 freq;
-	u32 bit_depth;
-	u32 valid_bit_depth;
-	u32 ch_cfg;
-	u32 interleaving_style;
-	u32 sample_type;
-	u32 ch_map;
-} __packed;
-
-struct skl_dfw_module_caps {
-	u32 set_params:2;
-	u32 rsvd:30;
-	u32 param_id;
-	u32 caps_size;
-	u32 caps[HDA_SST_CFG_MAX];
-};
-
-struct skl_dfw_pipe {
-	u8 pipe_id;
-	u8 pipe_priority;
-	u16 conn_type:4;
-	u16 rsvd:4;
-	u16 memory_pages:8;
-} __packed;
-
-struct skl_dfw_module {
-	u8 uuid[16];
-
-	u16 module_id;
-	u16 instance_id;
-	u32 max_mcps;
-	u32 mem_pages;
-	u32 obs;
-	u32 ibs;
-	u32 vbus_id;
-
-	u32 max_in_queue:8;
-	u32 max_out_queue:8;
-	u32 time_slot:8;
-	u32 core_id:4;
-	u32 rsvd1:4;
-
-	u32 module_type:8;
-	u32 conn_type:4;
-	u32 dev_type:4;
-	u32 hw_conn_type:4;
-	u32 rsvd2:12;
-
-	u32 params_fixup:8;
-	u32 converter:8;
-	u32 input_pin_type:1;
-	u32 output_pin_type:1;
-	u32 is_dynamic_in_pin:1;
-	u32 is_dynamic_out_pin:1;
-	u32 is_loadable:1;
-	u32 proc_domain:1;
-	u32 rsvd3:10;
-
-	struct skl_dfw_pipe pipe;
-	struct skl_dfw_module_fmt in_fmt[MAX_IN_QUEUE];
-	struct skl_dfw_module_fmt out_fmt[MAX_OUT_QUEUE];
-	struct skl_dfw_module_pin in_pin[MAX_IN_QUEUE];
-	struct skl_dfw_module_pin out_pin[MAX_OUT_QUEUE];
-	struct skl_dfw_module_caps caps;
-} __packed;
-
 struct skl_dfw_algo_data {
 	u32 set_params:2;
 	u32 rsvd:30;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 4/4] ASoC: Intel: Skylake: Parse manifest data
  2016-08-12  6:59 [PATCH 0/4] ASoC: Intel: Skylake: Add token support for topology data Vinod Koul
                   ` (2 preceding siblings ...)
  2016-08-12  6:59 ` [PATCH 3/4] ASoC: Intel: Skylake: Remove dfw config and associated structures Vinod Koul
@ 2016-08-12  6:59 ` Vinod Koul
  2016-08-22 17:47   ` Mark Brown
  2016-08-12 10:41 ` [PATCH 0/4] ASoC: Intel: Skylake: Add token support for topology data Mark Brown
  4 siblings, 1 reply; 15+ messages in thread
From: Vinod Koul @ 2016-08-12  6:59 UTC (permalink / raw)
  To: alsa-devel
  Cc: liam.r.girdwood, patches.audio, broonie, Vinod Koul, Shreyas NC

From: Shreyas NC <shreyas.nc@intel.com>

Topology manifest has lib names and lib count info. So,
define tokens to represent module private data and parse
these tokens to fill up the manifest structure in the driver
accordingly.

Signed-off-by: Shreyas NC <shreyas.nc@intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
---
 include/uapi/sound/snd_sst_tokens.h    |   8 +-
 sound/soc/intel/skylake/skl-topology.c | 194 ++++++++++++++++++++++++++++++++-
 2 files changed, 200 insertions(+), 2 deletions(-)

diff --git a/include/uapi/sound/snd_sst_tokens.h b/include/uapi/sound/snd_sst_tokens.h
index f56a932736ca..1ee2e943d66a 100644
--- a/include/uapi/sound/snd_sst_tokens.h
+++ b/include/uapi/sound/snd_sst_tokens.h
@@ -153,6 +153,10 @@
  *
  * %SKL_TKN_U32_PROC_DOMAIN:    Specify processing domain
  *
+ * %SKL_TKN_U32_LIB_COUNT:      Specifies the number of libraries
+ *
+ * %SKL_TKN_STR_LIB_NAME:       Specifies the library name
+ *
  * module_id and loadable flags dont have tokens as these values will be
  * read from the DSP FW manifest
  */
@@ -202,7 +206,9 @@ enum SKL_TKNS {
 	SKL_TKN_U32_CAPS_PARAMS_ID,
 	SKL_TKN_U32_CAPS_SIZE,
 	SKL_TKN_U32_PROC_DOMAIN,
-	SKL_TKN_MAX = SKL_TKN_U32_PROC_DOMAIN,
+	SKL_TKN_U32_LIB_COUNT,
+	SKL_TKN_STR_LIB_NAME,
+	SKL_TKN_MAX = SKL_TKN_STR_LIB_NAME,
 };
 
 #endif
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c
index df58691d0b3c..4d3d7e386bb9 100644
--- a/sound/soc/intel/skylake/skl-topology.c
+++ b/sound/soc/intel/skylake/skl-topology.c
@@ -2201,6 +2201,197 @@ static int skl_tplg_control_load(struct snd_soc_component *cmpnt,
 	return 0;
 }
 
+static int skl_tplg_fill_str_mfest_tkn(struct device *dev,
+		struct snd_soc_tplg_vendor_string_elem *str_elem,
+		struct skl_dfw_manifest *minfo)
+{
+	int tkn_count = 0;
+	static int ref_count;
+
+	switch (str_elem->token) {
+	case SKL_TKN_STR_LIB_NAME:
+		if (ref_count > minfo->lib_count - 1) {
+			ref_count = 0;
+			return -EINVAL;
+		}
+
+		strncpy(minfo->lib[ref_count].name, str_elem->string,
+				ARRAY_SIZE(minfo->lib[ref_count].name));
+		ref_count++;
+		tkn_count++;
+		break;
+
+	default:
+		dev_err(dev, "Not a string token %d", str_elem->token);
+		break;
+	}
+
+	return tkn_count;
+}
+
+static int skl_tplg_get_str_tkn(struct device *dev,
+		struct snd_soc_tplg_vendor_array *array,
+		struct skl_dfw_manifest *minfo)
+{
+	int tkn_count = 0, ret;
+	struct snd_soc_tplg_vendor_string_elem *str_elem;
+
+	str_elem = (struct snd_soc_tplg_vendor_string_elem *)array->value;
+	while (tkn_count < array->num_elems) {
+		ret = skl_tplg_fill_str_mfest_tkn(dev, str_elem, minfo);
+		str_elem++;
+
+		if (ret < 0)
+			return ret;
+
+		tkn_count = tkn_count + ret;
+	}
+
+	return tkn_count;
+}
+
+static int skl_tplg_get_int_tkn(struct device *dev,
+		struct snd_soc_tplg_vendor_value_elem *tkn_elem,
+		struct skl_dfw_manifest *minfo)
+{
+	int tkn_count = 0;
+
+	switch (tkn_elem->token) {
+	case SKL_TKN_U32_LIB_COUNT:
+		minfo->lib_count = tkn_elem->value;
+		tkn_count++;
+		break;
+
+	default:
+		dev_err(dev, "Not a manifest token %d", tkn_elem->token);
+		return -EINVAL;
+	}
+
+	return tkn_count;
+}
+
+/*
+ * Fill the manifest structure by parsing the tokens based on the
+ * type.
+ */
+static int skl_tplg_get_manifest_tkn(struct device *dev,
+		char *pvt_data, struct skl_dfw_manifest *minfo,
+		int block_size)
+{
+	int tkn_count = 0, ret;
+	int off = 0, tuple_size = 0;
+	struct snd_soc_tplg_vendor_array *array;
+	struct snd_soc_tplg_vendor_value_elem *tkn_elem;
+
+	if (block_size <= 0)
+		return -EINVAL;
+
+	while (tuple_size < block_size) {
+		array = (struct snd_soc_tplg_vendor_array *)(pvt_data + off);
+		off += array->size;
+		switch (array->type) {
+		case SND_SOC_TPLG_TUPLE_TYPE_STRING:
+			ret = skl_tplg_get_str_tkn(dev, array, minfo);
+
+			if (ret < 0)
+				return ret;
+			tkn_count += ret;
+
+			tuple_size += tkn_count *
+				sizeof(struct snd_soc_tplg_vendor_string_elem);
+			continue;
+
+		case SND_SOC_TPLG_TUPLE_TYPE_UUID:
+			dev_warn(dev, "no uuid tokens for skl tplf manifest");
+			continue;
+
+		default:
+			tkn_elem = array->value;
+			tkn_count = 0;
+			break;
+		}
+
+		while (tkn_count <= array->num_elems - 1) {
+			ret = skl_tplg_get_int_tkn(dev,
+					tkn_elem, minfo);
+			if (ret < 0)
+				return ret;
+
+			tkn_count = tkn_count + ret;
+			tkn_elem++;
+			tuple_size += tkn_count *
+				sizeof(struct snd_soc_tplg_vendor_value_elem);
+			break;
+		}
+		tkn_count = 0;
+	}
+
+	return 0;
+}
+
+/*
+ * Parse manifest private data for tokens. The private data block is
+ * preceded by descriptors for type and size of data block.
+ */
+static int skl_tplg_get_manifest_data(struct snd_soc_tplg_manifest *manifest,
+			struct device *dev, struct skl_dfw_manifest *minfo)
+{
+	struct snd_soc_tplg_vendor_array *array;
+	int num_blocks, block_size = 0, block_type, off = 0;
+	char *data;
+	int ret;
+
+	/* Read the NUM_DATA_BLOCKS descriptor */
+	array = (struct snd_soc_tplg_vendor_array *)manifest->priv.data;
+	ret = skl_tplg_get_desc_blocks(dev, array);
+	if (ret < 0)
+		return ret;
+	num_blocks = ret;
+
+	off += array->size;
+	array = (struct snd_soc_tplg_vendor_array *)
+			(manifest->priv.data + off);
+
+	/* Read the BLOCK_TYPE and BLOCK_SIZE descriptor */
+	while (num_blocks > 0) {
+		ret = skl_tplg_get_desc_blocks(dev, array);
+
+		if (ret < 0)
+			return ret;
+		block_type = ret;
+		off += array->size;
+
+		array = (struct snd_soc_tplg_vendor_array *)
+			(manifest->priv.data + off);
+
+		ret = skl_tplg_get_desc_blocks(dev, array);
+
+		if (ret < 0)
+			return ret;
+		block_size = ret;
+		off += array->size;
+
+		array = (struct snd_soc_tplg_vendor_array *)
+			(manifest->priv.data + off);
+
+		data = (manifest->priv.data + off);
+
+		if (block_type == SKL_TYPE_TUPLE) {
+			ret = skl_tplg_get_manifest_tkn(dev, data, minfo,
+					block_size);
+
+			if (ret < 0)
+				return ret;
+
+			--num_blocks;
+		} else {
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
 static int skl_manifest_load(struct snd_soc_component *cmpnt,
 				struct snd_soc_tplg_manifest *manifest)
 {
@@ -2215,7 +2406,8 @@ static int skl_manifest_load(struct snd_soc_component *cmpnt,
 		return 0;
 
 	minfo = &skl->skl_sst->manifest;
-	memcpy(minfo, manifest->priv.data, sizeof(struct skl_dfw_manifest));
+
+	skl_tplg_get_manifest_data(manifest, bus->dev, minfo);
 
 	if (minfo->lib_count > HDA_MAX_LIB) {
 		dev_err(bus->dev, "Exceeding max Library count. Got:%d\n",
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH 0/4] ASoC: Intel: Skylake: Add token support for topology data
  2016-08-12  6:59 [PATCH 0/4] ASoC: Intel: Skylake: Add token support for topology data Vinod Koul
                   ` (3 preceding siblings ...)
  2016-08-12  6:59 ` [PATCH 4/4] ASoC: Intel: Skylake: Parse manifest data Vinod Koul
@ 2016-08-12 10:41 ` Mark Brown
  2016-08-12 10:55   ` Vinod Koul
  4 siblings, 1 reply; 15+ messages in thread
From: Mark Brown @ 2016-08-12 10:41 UTC (permalink / raw)
  To: Vinod Koul; +Cc: liam.r.girdwood, patches.audio, alsa-devel


[-- Attachment #1.1: Type: text/plain, Size: 627 bytes --]

On Fri, Aug 12, 2016 at 12:29:49PM +0530, Vinod Koul wrote:
> With topology changes in alsa-lib, driver data for modules can now be
> passed in topology conf file using tuples.
> 
> These changes allow private data to represented by tuples of type UUID,
> byte, short, word and strings.

A question I ask quite often: the topology code has been in mainline
since v4.2 but still has a big old #error at the top preventing any
actual use from userspace.  We're now more than a year after the code
was originally merged and still no patches to actually make this ABI
usable from userspace.  Where are we at with that?

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 0/4] ASoC: Intel: Skylake: Add token support for topology data
  2016-08-12 10:41 ` [PATCH 0/4] ASoC: Intel: Skylake: Add token support for topology data Mark Brown
@ 2016-08-12 10:55   ` Vinod Koul
  2016-08-17  6:59     ` Mengdong Lin
  0 siblings, 1 reply; 15+ messages in thread
From: Vinod Koul @ 2016-08-12 10:55 UTC (permalink / raw)
  To: Mark Brown, liam.r.girdwood, Mengdong; +Cc: patches.audio, alsa-devel


[-- Attachment #1.1: Type: text/plain, Size: 959 bytes --]

On Fri, Aug 12, 2016 at 11:41:07AM +0100, Mark Brown wrote:
> On Fri, Aug 12, 2016 at 12:29:49PM +0530, Vinod Koul wrote:
> > With topology changes in alsa-lib, driver data for modules can now be
> > passed in topology conf file using tuples.
> > 
> > These changes allow private data to represented by tuples of type UUID,
> > byte, short, word and strings.
> 
> A question I ask quite often: the topology code has been in mainline
> since v4.2 but still has a big old #error at the top preventing any
> actual use from userspace.  We're now more than a year after the code
> was originally merged and still no patches to actually make this ABI
> usable from userspace.  Where are we at with that?

Mengdong was working on last set of features for providing DAIlinks. After
that we dont have any more updates planned on topology API.

So I think we cna remove it for current cycle. Mengdong cna you please
confirm..

Thanks
-- 
~Vinod

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 0/4] ASoC: Intel: Skylake: Add token support for topology data
  2016-08-12 10:55   ` Vinod Koul
@ 2016-08-17  6:59     ` Mengdong Lin
  2016-08-17 10:01       ` Mark Brown
  0 siblings, 1 reply; 15+ messages in thread
From: Mengdong Lin @ 2016-08-17  6:59 UTC (permalink / raw)
  To: Vinod Koul, Mark Brown, liam.r.girdwood, Mengdong
  Cc: patches.audio, alsa-devel



On 08/12/2016 06:55 PM, Vinod Koul wrote:
> On Fri, Aug 12, 2016 at 11:41:07AM +0100, Mark Brown wrote:
>> On Fri, Aug 12, 2016 at 12:29:49PM +0530, Vinod Koul wrote:
>>> With topology changes in alsa-lib, driver data for modules can now be
>>> passed in topology conf file using tuples.
>>>
>>> These changes allow private data to represented by tuples of type UUID,
>>> byte, short, word and strings.
>>
>> A question I ask quite often: the topology code has been in mainline
>> since v4.2 but still has a big old #error at the top preventing any
>> actual use from userspace.  We're now more than a year after the code
>> was originally merged and still no patches to actually make this ABI
>> usable from userspace.  Where are we at with that?
>
> Mengdong was working on last set of features for providing DAIlinks. After
> that we dont have any more updates planned on topology API.

There will be 2 more series to bring some topology ABI update. The code 
is ready and verified. And we will not modify ABI to break backward 
compatibility after this.

>
> So I think we cna remove it for current cycle. Mengdong cna you please
> confirm..

I think we may remove those #error after this cycle of upstreaming. 
We'll resume the patch upstreaming this week.

Thanks
Mengdong

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 0/4] ASoC: Intel: Skylake: Add token support for topology data
  2016-08-17  6:59     ` Mengdong Lin
@ 2016-08-17 10:01       ` Mark Brown
  2016-08-17 15:03         ` Lin, Mengdong
  0 siblings, 1 reply; 15+ messages in thread
From: Mark Brown @ 2016-08-17 10:01 UTC (permalink / raw)
  To: Mengdong Lin
  Cc: Vinod Koul, liam.r.girdwood, alsa-devel, patches.audio, Mengdong


[-- Attachment #1.1: Type: text/plain, Size: 489 bytes --]

On Wed, Aug 17, 2016 at 02:59:28PM +0800, Mengdong Lin wrote:

> There will be 2 more series to bring some topology ABI update. The code is
> ready and verified. And we will not modify ABI to break backward
> compatibility after this.

It's been over a year since this code was submitted as an ABI.  What are
these additional changes?  From where I'm sitting it is really difficult
to see that there's an end in sight here and we've had systems out that
need this for quite some time now.

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 0/4] ASoC: Intel: Skylake: Add token support for topology data
  2016-08-17 10:01       ` Mark Brown
@ 2016-08-17 15:03         ` Lin, Mengdong
  0 siblings, 0 replies; 15+ messages in thread
From: Lin, Mengdong @ 2016-08-17 15:03 UTC (permalink / raw)
  To: Mark Brown, Mengdong Lin
  Cc: Koul, Vinod, liam.r.girdwood, alsa-devel, Patches Audio

> -----Original Message-----
> From: Mark Brown [mailto:broonie@kernel.org]
> Sent: Wednesday, August 17, 2016 6:02 PM
> To: Mengdong Lin
> Cc: Koul, Vinod; liam.r.girdwood@linux.intel.com; Lin, Mengdong; Patches
> Audio; alsa-devel@alsa-project.org
> Subject: Re: [alsa-devel] [PATCH 0/4] ASoC: Intel: Skylake: Add token support
> for topology data
> 
> On Wed, Aug 17, 2016 at 02:59:28PM +0800, Mengdong Lin wrote:
> 
> > There will be 2 more series to bring some topology ABI update. The
> > code is ready and verified. And we will not modify ABI to break
> > backward compatibility after this.
> 
> It's been over a year since this code was submitted as an ABI.  What are
> these additional changes?  From where I'm sitting it is really difficult to see
> that there's an end in sight here and we've had systems out that need this
> for quite some time now.

One kernel series is for PCM (FE) and the other is for BE link. I'll submit them for review this week.

Thanks
Mengdong

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 4/4] ASoC: Intel: Skylake: Parse manifest data
  2016-08-12  6:59 ` [PATCH 4/4] ASoC: Intel: Skylake: Parse manifest data Vinod Koul
@ 2016-08-22 17:47   ` Mark Brown
  2016-08-23  4:02     ` Vinod Koul
  0 siblings, 1 reply; 15+ messages in thread
From: Mark Brown @ 2016-08-22 17:47 UTC (permalink / raw)
  To: Vinod Koul; +Cc: liam.r.girdwood, patches.audio, alsa-devel, Shreyas NC


[-- Attachment #1.1: Type: text/plain, Size: 376 bytes --]

On Fri, Aug 12, 2016 at 12:29:53PM +0530, Vinod Koul wrote:
> From: Shreyas NC <shreyas.nc@intel.com>
> 
> Topology manifest has lib names and lib count info. So,
> define tokens to represent module private data and parse
> these tokens to fill up the manifest structure in the driver
> accordingly.

This doesn't apply against current code, please check and resend.

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Applied "ASoC: Intel: Skylake: Remove dfw config and associated structures" to the asoc tree
  2016-08-12  6:59 ` [PATCH 3/4] ASoC: Intel: Skylake: Remove dfw config and associated structures Vinod Koul
@ 2016-08-22 17:59   ` Mark Brown
  0 siblings, 0 replies; 15+ messages in thread
From: Mark Brown @ 2016-08-22 17:59 UTC (permalink / raw)
  To: Shreyas NC
  Cc: Vinod Koul, liam.r.girdwood, alsa-devel, broonie, patches.audio

The patch

   ASoC: Intel: Skylake: Remove dfw config and associated structures

has been applied to the asoc tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 33ece7f9c8e8a2abfcca681ec9424b15271f7afb Mon Sep 17 00:00:00 2001
From: Shreyas NC <shreyas.nc@intel.com>
Date: Fri, 12 Aug 2016 12:29:52 +0530
Subject: [PATCH] ASoC: Intel: Skylake: Remove dfw config and associated
 structures

The skl_dfw_config structure is no longer required as the module
config is populated by parsing and reading the token values.

So, remove the structure.

Signed-off-by: Shreyas NC <shreyas.nc@intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/intel/skylake/skl-sst-utils.c      |  5 --
 sound/soc/intel/skylake/skl-tplg-interface.h | 73 ----------------------------
 2 files changed, 78 deletions(-)

diff --git a/sound/soc/intel/skylake/skl-sst-utils.c b/sound/soc/intel/skylake/skl-sst-utils.c
index e4865ea950d7..9ce93e9a03b5 100644
--- a/sound/soc/intel/skylake/skl-sst-utils.c
+++ b/sound/soc/intel/skylake/skl-sst-utils.c
@@ -28,11 +28,6 @@
 /* FW Extended Manifest Header id = $AE1 */
 #define SKL_EXT_MANIFEST_HEADER_MAGIC   0x31454124
 
-struct skl_dfw_module_mod {
-	char name[100];
-	struct skl_dfw_module skl_dfw_mod;
-};
-
 struct UUID {
 	u8 id[16];
 };
diff --git a/sound/soc/intel/skylake/skl-tplg-interface.h b/sound/soc/intel/skylake/skl-tplg-interface.h
index 281762eca0ab..e208724f9db3 100644
--- a/sound/soc/intel/skylake/skl-tplg-interface.h
+++ b/sound/soc/intel/skylake/skl-tplg-interface.h
@@ -148,79 +148,6 @@ enum skl_module_param_type {
 	SKL_PARAM_BIND
 };
 
-struct skl_dfw_module_pin {
-	u16 module_id;
-	u16 instance_id;
-} __packed;
-
-struct skl_dfw_module_fmt {
-	u32 channels;
-	u32 freq;
-	u32 bit_depth;
-	u32 valid_bit_depth;
-	u32 ch_cfg;
-	u32 interleaving_style;
-	u32 sample_type;
-	u32 ch_map;
-} __packed;
-
-struct skl_dfw_module_caps {
-	u32 set_params:2;
-	u32 rsvd:30;
-	u32 param_id;
-	u32 caps_size;
-	u32 caps[HDA_SST_CFG_MAX];
-};
-
-struct skl_dfw_pipe {
-	u8 pipe_id;
-	u8 pipe_priority;
-	u16 conn_type:4;
-	u16 rsvd:4;
-	u16 memory_pages:8;
-} __packed;
-
-struct skl_dfw_module {
-	u8 uuid[16];
-
-	u16 module_id;
-	u16 instance_id;
-	u32 max_mcps;
-	u32 mem_pages;
-	u32 obs;
-	u32 ibs;
-	u32 vbus_id;
-
-	u32 max_in_queue:8;
-	u32 max_out_queue:8;
-	u32 time_slot:8;
-	u32 core_id:4;
-	u32 rsvd1:4;
-
-	u32 module_type:8;
-	u32 conn_type:4;
-	u32 dev_type:4;
-	u32 hw_conn_type:4;
-	u32 rsvd2:12;
-
-	u32 params_fixup:8;
-	u32 converter:8;
-	u32 input_pin_type:1;
-	u32 output_pin_type:1;
-	u32 is_dynamic_in_pin:1;
-	u32 is_dynamic_out_pin:1;
-	u32 is_loadable:1;
-	u32 proc_domain:1;
-	u32 rsvd3:10;
-
-	struct skl_dfw_pipe pipe;
-	struct skl_dfw_module_fmt in_fmt[MAX_IN_QUEUE];
-	struct skl_dfw_module_fmt out_fmt[MAX_OUT_QUEUE];
-	struct skl_dfw_module_pin in_pin[MAX_IN_QUEUE];
-	struct skl_dfw_module_pin out_pin[MAX_OUT_QUEUE];
-	struct skl_dfw_module_caps caps;
-} __packed;
-
 struct skl_dfw_algo_data {
 	u32 set_params:2;
 	u32 rsvd:30;
-- 
2.8.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Applied "ASoC: Intel: Skylake: Parse vendor tokens to build module data" to the asoc tree
  2016-08-12  6:59 ` [PATCH 2/4] ASoC: Intel: Skylake: Parse vendor tokens to build module data Vinod Koul
@ 2016-08-22 17:59   ` Mark Brown
  0 siblings, 0 replies; 15+ messages in thread
From: Mark Brown @ 2016-08-22 17:59 UTC (permalink / raw)
  To: Shreyas NC
  Cc: Vinod Koul, liam.r.girdwood, alsa-devel, broonie, patches.audio

The patch

   ASoC: Intel: Skylake: Parse vendor tokens to build module data

has been applied to the asoc tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 6277e83292a2d4d88d150c0eb3004bd714ad8728 Mon Sep 17 00:00:00 2001
From: Shreyas NC <shreyas.nc@intel.com>
Date: Fri, 12 Aug 2016 12:29:51 +0530
Subject: [PATCH] ASoC: Intel: Skylake: Parse vendor tokens to build module
 data

Skl topology data is preceded by a descriptor for number of data
blocks, the size of the data block and type of data block. The
type of the data block can be either a tuple or a binary blob.

Private data is parsed based on data block type and module data
is filled accordingly.

Signed-off-by: Shreyas NC <shreyas.nc@intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/intel/skylake/skl-topology.c       | 645 ++++++++++++++++++++++-----
 sound/soc/intel/skylake/skl-tplg-interface.h |  10 +
 2 files changed, 545 insertions(+), 110 deletions(-)

diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c
index 4bc8f9c269db..000482e6e2f7 100644
--- a/sound/soc/intel/skylake/skl-topology.c
+++ b/sound/soc/intel/skylake/skl-topology.c
@@ -21,6 +21,7 @@
 #include <linux/firmware.h>
 #include <sound/soc.h>
 #include <sound/soc-topology.h>
+#include <uapi/sound/snd_sst_tokens.h>
 #include "skl-sst-dsp.h"
 #include "skl-sst-ipc.h"
 #include "skl-topology.h"
@@ -32,6 +33,8 @@
 #define SKL_CH_FIXUP_MASK		(1 << 0)
 #define SKL_RATE_FIXUP_MASK		(1 << 1)
 #define SKL_FMT_FIXUP_MASK		(1 << 2)
+#define SKL_IN_DIR_BIT_MASK		BIT(0)
+#define SKL_PIN_COUNT_MASK		GENMASK(7, 4)
 
 /*
  * SKL DSP driver modelling uses only few DAPM widgets so for rest we will
@@ -1468,85 +1471,570 @@ static const struct snd_soc_tplg_bytes_ext_ops skl_tlv_ops[] = {
 					skl_tplg_tlv_control_set},
 };
 
-/*
- * The topology binary passes the pin info for a module so initialize the pin
- * info passed into module instance
- */
-static void skl_fill_module_pin_info(struct skl_dfw_module_pin *dfw_pin,
-						struct skl_module_pin *m_pin,
-						bool is_dynamic, int max_pin)
+static int skl_tplg_fill_pipe_tkn(struct device *dev,
+			struct skl_pipe *pipe, u32 tkn,
+			u32 tkn_val)
 {
-	int i;
 
-	for (i = 0; i < max_pin; i++) {
-		m_pin[i].id.module_id = dfw_pin[i].module_id;
-		m_pin[i].id.instance_id = dfw_pin[i].instance_id;
-		m_pin[i].in_use = false;
-		m_pin[i].is_dynamic = is_dynamic;
-		m_pin[i].pin_state = SKL_PIN_UNBIND;
+	switch (tkn) {
+	case SKL_TKN_U32_PIPE_CONN_TYPE:
+		pipe->conn_type = tkn_val;
+		break;
+
+	case SKL_TKN_U32_PIPE_PRIORITY:
+		pipe->pipe_priority = tkn_val;
+		break;
+
+	case SKL_TKN_U32_PIPE_MEM_PGS:
+		pipe->memory_pages = tkn_val;
+		break;
+
+	default:
+		dev_err(dev, "Token not handled %d\n", tkn);
+		return -EINVAL;
 	}
+
+	return 0;
 }
 
 /*
- * Add pipeline from topology binary into driver pipeline list
- *
- * If already added we return that instance
- * Otherwise we create a new instance and add into driver list
+ * Add pipeline by parsing the relevant tokens
+ * Return an existing pipe if the pipe already exists.
  */
-static struct skl_pipe *skl_tplg_add_pipe(struct device *dev,
-			struct skl *skl, struct skl_dfw_pipe *dfw_pipe)
+static int skl_tplg_add_pipe(struct device *dev,
+		struct skl_module_cfg *mconfig, struct skl *skl,
+		struct snd_soc_tplg_vendor_value_elem *tkn_elem)
 {
 	struct skl_pipeline *ppl;
 	struct skl_pipe *pipe;
 	struct skl_pipe_params *params;
 
 	list_for_each_entry(ppl, &skl->ppl_list, node) {
-		if (ppl->pipe->ppl_id == dfw_pipe->pipe_id)
-			return ppl->pipe;
+		if (ppl->pipe->ppl_id == tkn_elem->value) {
+			mconfig->pipe = ppl->pipe;
+			return EEXIST;
+		}
 	}
 
 	ppl = devm_kzalloc(dev, sizeof(*ppl), GFP_KERNEL);
 	if (!ppl)
-		return NULL;
+		return -ENOMEM;
 
 	pipe = devm_kzalloc(dev, sizeof(*pipe), GFP_KERNEL);
 	if (!pipe)
-		return NULL;
+		return -ENOMEM;
 
 	params = devm_kzalloc(dev, sizeof(*params), GFP_KERNEL);
 	if (!params)
-		return NULL;
+		return -ENOMEM;
 
-	pipe->ppl_id = dfw_pipe->pipe_id;
-	pipe->memory_pages = dfw_pipe->memory_pages;
-	pipe->pipe_priority = dfw_pipe->pipe_priority;
-	pipe->conn_type = dfw_pipe->conn_type;
-	pipe->state = SKL_PIPE_INVALID;
 	pipe->p_params = params;
+	pipe->ppl_id = tkn_elem->value;
 	INIT_LIST_HEAD(&pipe->w_list);
 
 	ppl->pipe = pipe;
 	list_add(&ppl->node, &skl->ppl_list);
 
-	return ppl->pipe;
+	mconfig->pipe = pipe;
+	mconfig->pipe->state = SKL_PIPE_INVALID;
+
+	return 0;
+}
+
+static int skl_tplg_fill_pin(struct device *dev, u32 tkn,
+			struct skl_module_pin *m_pin,
+			int pin_index, u32 value)
+{
+	switch (tkn) {
+	case SKL_TKN_U32_PIN_MOD_ID:
+		m_pin[pin_index].id.module_id = value;
+		break;
+
+	case SKL_TKN_U32_PIN_INST_ID:
+		m_pin[pin_index].id.instance_id = value;
+		break;
+
+	default:
+		dev_err(dev, "%d Not a pin token\n", value);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/*
+ * Parse for pin config specific tokens to fill up the
+ * module private data
+ */
+static int skl_tplg_fill_pins_info(struct device *dev,
+		struct skl_module_cfg *mconfig,
+		struct snd_soc_tplg_vendor_value_elem *tkn_elem,
+		int dir, int pin_count)
+{
+	int ret;
+	struct skl_module_pin *m_pin;
+
+	switch (dir) {
+	case SKL_DIR_IN:
+		m_pin = mconfig->m_in_pin;
+		break;
+
+	case SKL_DIR_OUT:
+		m_pin = mconfig->m_out_pin;
+		break;
+
+	default:
+		dev_err(dev, "Invalid direction value");
+		return -EINVAL;
+	}
+
+	ret = skl_tplg_fill_pin(dev, tkn_elem->token,
+			m_pin, pin_count, tkn_elem->value);
+
+	if (ret < 0)
+		return ret;
+
+	m_pin[pin_count].in_use = false;
+	m_pin[pin_count].pin_state = SKL_PIN_UNBIND;
+
+	return 0;
 }
 
-static void skl_tplg_fill_fmt(struct skl_module_fmt *dst_fmt,
-				struct skl_dfw_module_fmt *src_fmt,
-				int pins)
+/*
+ * Fill up input/output module config format based
+ * on the direction
+ */
+static int skl_tplg_fill_fmt(struct device *dev,
+		struct skl_module_cfg *mconfig,	u32 tkn,
+		u32 value, u32 dir, u32 pin_count)
+{
+	struct skl_module_fmt *dst_fmt;
+
+	switch (dir) {
+	case SKL_DIR_IN:
+		dst_fmt = mconfig->in_fmt;
+		dst_fmt += pin_count;
+		break;
+
+	case SKL_DIR_OUT:
+		dst_fmt = mconfig->out_fmt;
+		dst_fmt += pin_count;
+		break;
+
+	default:
+		dev_err(dev, "Invalid direction value");
+		return -EINVAL;
+	}
+
+	switch (tkn) {
+	case SKL_TKN_U32_FMT_CH:
+		dst_fmt->channels  = value;
+		break;
+
+	case SKL_TKN_U32_FMT_FREQ:
+		dst_fmt->s_freq = value;
+		break;
+
+	case SKL_TKN_U32_FMT_BIT_DEPTH:
+		dst_fmt->bit_depth = value;
+		break;
+
+	case SKL_TKN_U32_FMT_SAMPLE_SIZE:
+		dst_fmt->valid_bit_depth = value;
+		break;
+
+	case SKL_TKN_U32_FMT_CH_CONFIG:
+		dst_fmt->ch_cfg = value;
+		break;
+
+	case SKL_TKN_U32_FMT_INTERLEAVE:
+		dst_fmt->interleaving_style = value;
+		break;
+
+	case SKL_TKN_U32_FMT_SAMPLE_TYPE:
+		dst_fmt->sample_type = value;
+		break;
+
+	case SKL_TKN_U32_FMT_CH_MAP:
+		dst_fmt->ch_map = value;
+		break;
+
+	default:
+		dev_err(dev, "Invalid token %d", tkn);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int skl_tplg_get_uuid(struct device *dev, struct skl_module_cfg *mconfig,
+	      struct snd_soc_tplg_vendor_uuid_elem *uuid_tkn)
+{
+	if (uuid_tkn->token == SKL_TKN_UUID)
+		memcpy(&mconfig->guid, &uuid_tkn->uuid, 16);
+	else {
+		dev_err(dev, "Not an UUID token tkn %d", uuid_tkn->token);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void skl_tplg_fill_pin_dynamic_val(
+		struct skl_module_pin *mpin, u32 pin_count, u32 value)
 {
 	int i;
 
-	for (i = 0; i < pins; i++) {
-		dst_fmt[i].channels  = src_fmt[i].channels;
-		dst_fmt[i].s_freq = src_fmt[i].freq;
-		dst_fmt[i].bit_depth = src_fmt[i].bit_depth;
-		dst_fmt[i].valid_bit_depth = src_fmt[i].valid_bit_depth;
-		dst_fmt[i].ch_cfg = src_fmt[i].ch_cfg;
-		dst_fmt[i].ch_map = src_fmt[i].ch_map;
-		dst_fmt[i].interleaving_style = src_fmt[i].interleaving_style;
-		dst_fmt[i].sample_type = src_fmt[i].sample_type;
+	for (i = 0; i < pin_count; i++)
+		mpin[i].is_dynamic = value;
+}
+
+/*
+ * Parse tokens to fill up the module private data
+ */
+static int skl_tplg_get_token(struct device *dev,
+		struct snd_soc_tplg_vendor_value_elem *tkn_elem,
+		struct skl *skl, struct skl_module_cfg *mconfig)
+{
+	int tkn_count = 0;
+	int ret;
+	static int is_pipe_exists;
+	static int pin_index, dir;
+
+	if (tkn_elem->token > SKL_TKN_MAX)
+		return -EINVAL;
+
+	switch (tkn_elem->token) {
+	case SKL_TKN_U8_IN_QUEUE_COUNT:
+		mconfig->max_in_queue = tkn_elem->value;
+		mconfig->m_in_pin = devm_kzalloc(dev, mconfig->max_in_queue *
+					sizeof(*mconfig->m_in_pin),
+					GFP_KERNEL);
+		if (!mconfig->m_in_pin)
+			return -ENOMEM;
+
+		break;
+
+	case SKL_TKN_U8_OUT_QUEUE_COUNT:
+		mconfig->max_out_queue = tkn_elem->value;
+		mconfig->m_out_pin = devm_kzalloc(dev, mconfig->max_out_queue *
+					sizeof(*mconfig->m_out_pin),
+					GFP_KERNEL);
+
+		if (!mconfig->m_out_pin)
+			return -ENOMEM;
+
+		break;
+
+	case SKL_TKN_U8_DYN_IN_PIN:
+		if (!mconfig->m_in_pin)
+			return -ENOMEM;
+
+		skl_tplg_fill_pin_dynamic_val(mconfig->m_in_pin,
+			mconfig->max_in_queue, tkn_elem->value);
+
+		break;
+
+	case SKL_TKN_U8_DYN_OUT_PIN:
+		if (!mconfig->m_out_pin)
+			return -ENOMEM;
+
+		skl_tplg_fill_pin_dynamic_val(mconfig->m_out_pin,
+			mconfig->max_out_queue, tkn_elem->value);
+
+		break;
+
+	case SKL_TKN_U8_TIME_SLOT:
+		mconfig->time_slot = tkn_elem->value;
+		break;
+
+	case SKL_TKN_U8_CORE_ID:
+		mconfig->core_id = tkn_elem->value;
+
+	case SKL_TKN_U8_MOD_TYPE:
+		mconfig->m_type = tkn_elem->value;
+		break;
+
+	case SKL_TKN_U8_DEV_TYPE:
+		mconfig->dev_type = tkn_elem->value;
+		break;
+
+	case SKL_TKN_U8_HW_CONN_TYPE:
+		mconfig->hw_conn_type = tkn_elem->value;
+		break;
+
+	case SKL_TKN_U16_MOD_INST_ID:
+		mconfig->id.instance_id =
+		tkn_elem->value;
+		break;
+
+	case SKL_TKN_U32_MEM_PAGES:
+		mconfig->mem_pages = tkn_elem->value;
+		break;
+
+	case SKL_TKN_U32_MAX_MCPS:
+		mconfig->mcps = tkn_elem->value;
+		break;
+
+	case SKL_TKN_U32_OBS:
+		mconfig->obs = tkn_elem->value;
+		break;
+
+	case SKL_TKN_U32_IBS:
+		mconfig->ibs = tkn_elem->value;
+		break;
+
+	case SKL_TKN_U32_VBUS_ID:
+		mconfig->vbus_id = tkn_elem->value;
+		break;
+
+	case SKL_TKN_U32_PARAMS_FIXUP:
+		mconfig->params_fixup = tkn_elem->value;
+		break;
+
+	case SKL_TKN_U32_CONVERTER:
+		mconfig->converter = tkn_elem->value;
+		break;
+
+	case SKL_TKN_U32_PIPE_ID:
+		ret = skl_tplg_add_pipe(dev,
+				mconfig, skl, tkn_elem);
+
+		if (ret < 0)
+			return is_pipe_exists;
+
+		if (ret == EEXIST)
+			is_pipe_exists = 1;
+
+		break;
+
+	case SKL_TKN_U32_PIPE_CONN_TYPE:
+	case SKL_TKN_U32_PIPE_PRIORITY:
+	case SKL_TKN_U32_PIPE_MEM_PGS:
+		if (is_pipe_exists) {
+			ret = skl_tplg_fill_pipe_tkn(dev, mconfig->pipe,
+					tkn_elem->token, tkn_elem->value);
+			if (ret < 0)
+				return ret;
+		}
+
+		break;
+
+	/*
+	 * SKL_TKN_U32_DIR_PIN_COUNT token has the value for both
+	 * direction and the pin count. The first four bits represent
+	 * direction and next four the pin count.
+	 */
+	case SKL_TKN_U32_DIR_PIN_COUNT:
+		dir = tkn_elem->value & SKL_IN_DIR_BIT_MASK;
+		pin_index = (tkn_elem->value &
+			SKL_PIN_COUNT_MASK) >> 4;
+
+		break;
+
+	case SKL_TKN_U32_FMT_CH:
+	case SKL_TKN_U32_FMT_FREQ:
+	case SKL_TKN_U32_FMT_BIT_DEPTH:
+	case SKL_TKN_U32_FMT_SAMPLE_SIZE:
+	case SKL_TKN_U32_FMT_CH_CONFIG:
+	case SKL_TKN_U32_FMT_INTERLEAVE:
+	case SKL_TKN_U32_FMT_SAMPLE_TYPE:
+	case SKL_TKN_U32_FMT_CH_MAP:
+		ret = skl_tplg_fill_fmt(dev, mconfig, tkn_elem->token,
+				tkn_elem->value, dir, pin_index);
+
+		if (ret < 0)
+			return ret;
+
+		break;
+
+	case SKL_TKN_U32_PIN_MOD_ID:
+	case SKL_TKN_U32_PIN_INST_ID:
+		ret = skl_tplg_fill_pins_info(dev,
+				mconfig, tkn_elem, dir,
+				pin_index);
+		if (ret < 0)
+			return ret;
+
+		break;
+
+	case SKL_TKN_U32_CAPS_SIZE:
+		mconfig->formats_config.caps_size =
+			tkn_elem->value;
+
+		break;
+
+	case SKL_TKN_U32_PROC_DOMAIN:
+		mconfig->domain =
+			tkn_elem->value;
+
+		break;
+
+	case SKL_TKN_U8_IN_PIN_TYPE:
+	case SKL_TKN_U8_OUT_PIN_TYPE:
+	case SKL_TKN_U8_CONN_TYPE:
+		break;
+
+	default:
+		dev_err(dev, "Token %d not handled\n",
+				tkn_elem->token);
+		return -EINVAL;
 	}
+
+	tkn_count++;
+
+	return tkn_count;
+}
+
+/*
+ * Parse the vendor array for specific tokens to construct
+ * module private data
+ */
+static int skl_tplg_get_tokens(struct device *dev,
+		char *pvt_data,	struct skl *skl,
+		struct skl_module_cfg *mconfig, int block_size)
+{
+	struct snd_soc_tplg_vendor_array *array;
+	struct snd_soc_tplg_vendor_value_elem *tkn_elem;
+	int tkn_count = 0, ret;
+	int off = 0, tuple_size = 0;
+
+	if (block_size <= 0)
+		return -EINVAL;
+
+	while (tuple_size < block_size) {
+		array = (struct snd_soc_tplg_vendor_array *)(pvt_data + off);
+
+		off += array->size;
+
+		switch (array->type) {
+		case SND_SOC_TPLG_TUPLE_TYPE_STRING:
+			dev_warn(dev, "no string tokens expected for skl tplg");
+			continue;
+
+		case SND_SOC_TPLG_TUPLE_TYPE_UUID:
+			ret = skl_tplg_get_uuid(dev, mconfig, array->uuid);
+			if (ret < 0)
+				return ret;
+
+			tuple_size += sizeof(*array->uuid);
+
+			continue;
+
+		default:
+			tkn_elem = array->value;
+			tkn_count = 0;
+			break;
+		}
+
+		while (tkn_count <= (array->num_elems - 1)) {
+			ret = skl_tplg_get_token(dev, tkn_elem,
+					skl, mconfig);
+
+			if (ret < 0)
+				return ret;
+
+			tkn_count = tkn_count + ret;
+			tkn_elem++;
+		}
+
+		tuple_size += tkn_count * sizeof(*tkn_elem);
+	}
+
+	return 0;
+}
+
+/*
+ * Every data block is preceded by a descriptor to read the number
+ * of data blocks, they type of the block and it's size
+ */
+static int skl_tplg_get_desc_blocks(struct device *dev,
+		struct snd_soc_tplg_vendor_array *array)
+{
+	struct snd_soc_tplg_vendor_value_elem *tkn_elem;
+
+	tkn_elem = array->value;
+
+	switch (tkn_elem->token) {
+	case SKL_TKN_U8_NUM_BLOCKS:
+	case SKL_TKN_U8_BLOCK_TYPE:
+	case SKL_TKN_U16_BLOCK_SIZE:
+		return tkn_elem->value;
+
+	default:
+		dev_err(dev, "Invalid descriptor token %d", tkn_elem->token);
+		break;
+	}
+
+	return -EINVAL;
+}
+
+/*
+ * Parse the private data for the token and corresponding value.
+ * The private data can have multiple data blocks. So, a data block
+ * is preceded by a descriptor for number of blocks and a descriptor
+ * for the type and size of the suceeding data block.
+ */
+static int skl_tplg_get_pvt_data(struct snd_soc_tplg_dapm_widget *tplg_w,
+				struct skl *skl, struct device *dev,
+				struct skl_module_cfg *mconfig)
+{
+	struct snd_soc_tplg_vendor_array *array;
+	int num_blocks, block_size = 0, block_type, off = 0;
+	char *data;
+	int ret;
+
+	/* Read the NUM_DATA_BLOCKS descriptor */
+	array = (struct snd_soc_tplg_vendor_array *)tplg_w->priv.data;
+	ret = skl_tplg_get_desc_blocks(dev, array);
+	if (ret < 0)
+		return ret;
+	num_blocks = ret;
+
+	off += array->size;
+	array = (struct snd_soc_tplg_vendor_array *)(tplg_w->priv.data + off);
+
+	/* Read the BLOCK_TYPE and BLOCK_SIZE descriptor */
+	while (num_blocks > 0) {
+		ret = skl_tplg_get_desc_blocks(dev, array);
+
+		if (ret < 0)
+			return ret;
+		block_type = ret;
+		off += array->size;
+
+		array = (struct snd_soc_tplg_vendor_array *)
+			(tplg_w->priv.data + off);
+
+		ret = skl_tplg_get_desc_blocks(dev, array);
+
+		if (ret < 0)
+			return ret;
+		block_size = ret;
+		off += array->size;
+
+		array = (struct snd_soc_tplg_vendor_array *)
+			(tplg_w->priv.data + off);
+
+		data = (tplg_w->priv.data + off);
+
+		if (block_type == SKL_TYPE_TUPLE) {
+			ret = skl_tplg_get_tokens(dev, data,
+					skl, mconfig, block_size);
+
+			if (ret < 0)
+				return ret;
+
+			--num_blocks;
+		} else {
+			if (mconfig->formats_config.caps_size > 0)
+				memcpy(mconfig->formats_config.caps, data,
+					mconfig->formats_config.caps_size);
+			--num_blocks;
+		}
+	}
+
+	return 0;
 }
 
 static void skl_clear_pin_config(struct snd_soc_platform *platform,
@@ -1614,9 +2102,6 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt,
 	struct skl *skl = ebus_to_skl(ebus);
 	struct hdac_bus *bus = ebus_to_hbus(ebus);
 	struct skl_module_cfg *mconfig;
-	struct skl_pipe *pipe;
-	struct skl_dfw_module *dfw_config =
-				(struct skl_dfw_module *)tplg_w->priv.data;
 
 	if (!tplg_w->priv.size)
 		goto bind_event;
@@ -1627,77 +2112,17 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt,
 		return -ENOMEM;
 
 	w->priv = mconfig;
-	memcpy(&mconfig->guid, &dfw_config->uuid, 16);
 
 	/*
 	 * module binary can be loaded later, so set it to query when
 	 * module is load for a use case
 	 */
 	mconfig->id.module_id = -1;
-	mconfig->id.instance_id = dfw_config->instance_id;
-	mconfig->mcps = dfw_config->max_mcps;
-	mconfig->ibs = dfw_config->ibs;
-	mconfig->obs = dfw_config->obs;
-	mconfig->core_id = dfw_config->core_id;
-	mconfig->max_in_queue = dfw_config->max_in_queue;
-	mconfig->max_out_queue = dfw_config->max_out_queue;
-	mconfig->is_loadable = dfw_config->is_loadable;
-	mconfig->domain = dfw_config->proc_domain;
-	skl_tplg_fill_fmt(mconfig->in_fmt, dfw_config->in_fmt,
-						MODULE_MAX_IN_PINS);
-	skl_tplg_fill_fmt(mconfig->out_fmt, dfw_config->out_fmt,
-						MODULE_MAX_OUT_PINS);
-
-	mconfig->params_fixup = dfw_config->params_fixup;
-	mconfig->converter = dfw_config->converter;
-	mconfig->m_type = dfw_config->module_type;
-	mconfig->vbus_id = dfw_config->vbus_id;
-	mconfig->mem_pages = dfw_config->mem_pages;
-
-	pipe = skl_tplg_add_pipe(bus->dev, skl, &dfw_config->pipe);
-	if (pipe)
-		mconfig->pipe = pipe;
-
-	mconfig->dev_type = dfw_config->dev_type;
-	mconfig->hw_conn_type = dfw_config->hw_conn_type;
-	mconfig->time_slot = dfw_config->time_slot;
-	mconfig->formats_config.caps_size = dfw_config->caps.caps_size;
-
-	mconfig->m_in_pin = devm_kzalloc(bus->dev, (mconfig->max_in_queue) *
-						sizeof(*mconfig->m_in_pin),
-						GFP_KERNEL);
-	if (!mconfig->m_in_pin)
-		return -ENOMEM;
-
-	mconfig->m_out_pin = devm_kzalloc(bus->dev, (mconfig->max_out_queue) *
-						sizeof(*mconfig->m_out_pin),
-						GFP_KERNEL);
-	if (!mconfig->m_out_pin)
-		return -ENOMEM;
-
-	skl_fill_module_pin_info(dfw_config->in_pin, mconfig->m_in_pin,
-						dfw_config->is_dynamic_in_pin,
-						mconfig->max_in_queue);
-
-	skl_fill_module_pin_info(dfw_config->out_pin, mconfig->m_out_pin,
-						 dfw_config->is_dynamic_out_pin,
-							mconfig->max_out_queue);
-
-
-	if (mconfig->formats_config.caps_size == 0)
-		goto bind_event;
-
-	mconfig->formats_config.caps = (u32 *)devm_kzalloc(bus->dev,
-			mconfig->formats_config.caps_size, GFP_KERNEL);
-
-	if (mconfig->formats_config.caps == NULL)
-		return -ENOMEM;
-
-	memcpy(mconfig->formats_config.caps, dfw_config->caps.caps,
-						 dfw_config->caps.caps_size);
-	mconfig->formats_config.param_id = dfw_config->caps.param_id;
-	mconfig->formats_config.set_params = dfw_config->caps.set_params;
 
+	/* Parse private data for tuples */
+	ret = skl_tplg_get_pvt_data(tplg_w, skl, bus->dev, mconfig);
+	if (ret < 0)
+		return ret;
 bind_event:
 	if (tplg_w->event_type == 0) {
 		dev_dbg(bus->dev, "ASoC: No event handler required\n");
diff --git a/sound/soc/intel/skylake/skl-tplg-interface.h b/sound/soc/intel/skylake/skl-tplg-interface.h
index bd8b4ae43557..281762eca0ab 100644
--- a/sound/soc/intel/skylake/skl-tplg-interface.h
+++ b/sound/soc/intel/skylake/skl-tplg-interface.h
@@ -241,4 +241,14 @@ struct skl_dfw_manifest {
 	struct lib_info lib[HDA_MAX_LIB];
 } __packed;
 
+enum skl_tkn_dir {
+	SKL_DIR_IN,
+	SKL_DIR_OUT
+};
+
+enum skl_tuple_type {
+	SKL_TYPE_TUPLE,
+	SKL_TYPE_DATA
+};
+
 #endif
-- 
2.8.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Applied "ASoC: uapi: Intel: Skylake: Define vendor specific tokens" to the asoc tree
  2016-08-12  6:59 ` [PATCH 1/4] ASoC: uapi: Intel: Skylake: Define vendor specific tokens Vinod Koul
@ 2016-08-22 17:59   ` Mark Brown
  0 siblings, 0 replies; 15+ messages in thread
From: Mark Brown @ 2016-08-22 17:59 UTC (permalink / raw)
  To: Shreyas NC
  Cc: Vinod Koul, liam.r.girdwood, alsa-devel, broonie, patches.audio

The patch

   ASoC: uapi: Intel: Skylake: Define vendor specific tokens

has been applied to the asoc tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 15f0d4f531d84015511dbdc2512e5a77c0173d49 Mon Sep 17 00:00:00 2001
From: Shreyas NC <shreyas.nc@intel.com>
Date: Fri, 12 Aug 2016 12:29:50 +0530
Subject: [PATCH] ASoC: uapi: Intel: Skylake: Define vendor specific tokens

With recent topology changes in alsa-lib, driver data for
modules can now be passed in topology conf file using tuples.

This patch defines vendor specific tokens to describe private
data with tuples.

The allowed token types are UUID, string, bool, byte, short and
word. These tokens will be referenced by the vendor tuples in
the conf file.

In the topology conf file, multiple data blocks can be defined
for a widget which can be either tuple vendor array or blob. So,
each data block will be preceded by a descriptor to identify
size and type of block. These descriptors will be token
value pairs.

Tokens for module_id and loadable flag are not defined as these
are read from the DSP FW manifest.

Signed-off-by: Shreyas NC <shreyas.nc@intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 include/uapi/sound/Kbuild           |   1 +
 include/uapi/sound/snd_sst_tokens.h | 208 ++++++++++++++++++++++++++++++++++++
 2 files changed, 209 insertions(+)
 create mode 100644 include/uapi/sound/snd_sst_tokens.h

diff --git a/include/uapi/sound/Kbuild b/include/uapi/sound/Kbuild
index 691984cb0b91..9578d8bdbf31 100644
--- a/include/uapi/sound/Kbuild
+++ b/include/uapi/sound/Kbuild
@@ -13,3 +13,4 @@ header-y += sb16_csp.h
 header-y += sfnt_info.h
 header-y += tlv.h
 header-y += usb_stream.h
+header-y += snd_sst_tokens.h
diff --git a/include/uapi/sound/snd_sst_tokens.h b/include/uapi/sound/snd_sst_tokens.h
new file mode 100644
index 000000000000..f56a932736ca
--- /dev/null
+++ b/include/uapi/sound/snd_sst_tokens.h
@@ -0,0 +1,208 @@
+/*
+ * snd_sst_tokens.h - Intel SST tokens definition
+ *
+ * Copyright (C) 2016 Intel Corp
+ * Author: Shreyas NC <shreyas.nc@intel.com>
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+#ifndef __SND_SST_TOKENS_H__
+#define __SND_SST_TOKENS_H__
+
+/**
+ * %SKL_TKN_UUID:               Module UUID
+ *
+ * %SKL_TKN_U8_BLOCK_TYPE:      Type of the private data block.Can be:
+ *                              tuples, bytes, short and words
+ *
+ * %SKL_TKN_U8_IN_PIN_TYPE:     Input pin type,
+ *                              homogenous=0, heterogenous=1
+ *
+ * %SKL_TKN_U8_OUT_PIN_TYPE:    Output pin type,
+ *                              homogenous=0, heterogenous=1
+ * %SKL_TKN_U8_DYN_IN_PIN:      Configure Input pin dynamically
+ *                              if true
+ *
+ * %SKL_TKN_U8_DYN_OUT_PIN:     Configure Output pin dynamically
+ *                              if true
+ *
+ * %SKL_TKN_U8_IN_QUEUE_COUNT:  Store the number of Input pins
+ *
+ * %SKL_TKN_U8_OUT_QUEUE_COUNT: Store the number of Output pins
+ *
+ * %SKL_TKN_U8_TIME_SLOT:       TDM slot number
+ *
+ * %SKL_TKN_U8_CORE_ID:         Stores module affinity value.Can take
+ *                              the values:
+ *                              SKL_AFFINITY_CORE_0 = 0,
+ *                              SKL_AFFINITY_CORE_1,
+ *                              SKL_AFFINITY_CORE_MAX
+ *
+ * %SKL_TKN_U8_MOD_TYPE:        Module type value.
+ *
+ * %SKL_TKN_U8_CONN_TYPE:       Module connection type can be a FE,
+ *                              BE or NONE as defined :
+ *                              SKL_PIPE_CONN_TYPE_NONE = 0,
+ *                              SKL_PIPE_CONN_TYPE_FE = 1 (HOST_DMA)
+ *                              SKL_PIPE_CONN_TYPE_BE = 2 (LINK_DMA)
+ *
+ * %SKL_TKN_U8_DEV_TYPE:        Type of device to which the module is
+ *                              connected
+ *                              Can take the values:
+ *                              SKL_DEVICE_BT = 0x0,
+ *                              SKL_DEVICE_DMIC = 0x1,
+ *                              SKL_DEVICE_I2S = 0x2,
+ *                              SKL_DEVICE_SLIMBUS = 0x3,
+ *                              SKL_DEVICE_HDALINK = 0x4,
+ *                              SKL_DEVICE_HDAHOST = 0x5,
+ *                              SKL_DEVICE_NONE
+ *
+ * %SKL_TKN_U8_HW_CONN_TYPE:    Connection type of the HW to which the
+ *                              module is connected
+ *                              SKL_CONN_NONE = 0,
+ *                              SKL_CONN_SOURCE = 1,
+ *                              SKL_CONN_SINK = 2
+ *
+ * %SKL_TKN_U16_PIN_INST_ID:    Stores the pin instance id
+ *
+ * %SKL_TKN_U16_MOD_INST_ID:    Stores the mdule instance id
+ *
+ * %SKL_TKN_U32_MAX_MCPS:       Module max mcps value
+ *
+ * %SKL_TKN_U32_MEM_PAGES:      Module resource pages
+ *
+ * %SKL_TKN_U32_OBS:            Stores Output Buffer size
+ *
+ * %SKL_TKN_U32_IBS:            Stores input buffer size
+ *
+ * %SKL_TKN_U32_VBUS_ID:        Module VBUS_ID. PDM=0, SSP0=0,
+ *                              SSP1=1,SSP2=2,
+ *                              SSP3=3, SSP4=4,
+ *                              SSP5=5, SSP6=6,INVALID
+ *
+ * %SKL_TKN_U32_PARAMS_FIXUP:   Module Params fixup mask
+ * %SKL_TKN_U32_CONVERTER:      Module params converter mask
+ * %SKL_TKN_U32_PIPE_ID:        Stores the pipe id
+ *
+ * %SKL_TKN_U32_PIPE_CONN_TYPE: Type of the token to which the pipe is
+ *                              connected to. It can be
+ *                              SKL_PIPE_CONN_TYPE_NONE = 0,
+ *                              SKL_PIPE_CONN_TYPE_FE = 1 (HOST_DMA),
+ *                              SKL_PIPE_CONN_TYPE_BE = 2 (LINK_DMA),
+ *
+ * %SKL_TKN_U32_PIPE_PRIORITY:  Pipe priority value
+ * %SKL_TKN_U32_PIPE_MEM_PGS:   Pipe resource pages
+ *
+ * %SKL_TKN_U32_DIR_PIN_COUNT:  Value for the direction to set input/output
+ *                              formats and the pin count.
+ *                              The first 4 bits have the direction
+ *                              value and the next 4 have
+ *                              the pin count value.
+ *                              SKL_DIR_IN = 0, SKL_DIR_OUT = 1.
+ *                              The input and output formats
+ *                              share the same set of tokens
+ *                              with the distinction between input
+ *                              and output made by reading direction
+ *                              token.
+ *
+ * %SKL_TKN_U32_FMT_CH:         Supported channel count
+ *
+ * %SKL_TKN_U32_FMT_FREQ:       Supported frequency/sample rate
+ *
+ * %SKL_TKN_U32_FMT_BIT_DEPTH:  Supported container size
+ *
+ * %SKL_TKN_U32_FMT_SAMPLE_SIZE:Number of samples in the container
+ *
+ * %SKL_TKN_U32_FMT_CH_CONFIG:  Supported channel configurations for the
+ *                              input/output.
+ *
+ * %SKL_TKN_U32_FMT_INTERLEAVE: Interleaving style which can be per
+ *                              channel or per sample. The values can be :
+ *                              SKL_INTERLEAVING_PER_CHANNEL = 0,
+ *                              SKL_INTERLEAVING_PER_SAMPLE = 1,
+ *
+ * %SKL_TKN_U32_FMT_SAMPLE_TYPE:
+ *                              Specifies the sample type. Can take the
+ *                              values: SKL_SAMPLE_TYPE_INT_MSB = 0,
+ *                              SKL_SAMPLE_TYPE_INT_LSB = 1,
+ *                              SKL_SAMPLE_TYPE_INT_SIGNED = 2,
+ *                              SKL_SAMPLE_TYPE_INT_UNSIGNED = 3,
+ *                              SKL_SAMPLE_TYPE_FLOAT = 4
+ *
+ * %SKL_TKN_U32_CH_MAP:         Channel map values
+ * %SKL_TKN_U32_MOD_SET_PARAMS: It can take these values:
+ *                              SKL_PARAM_DEFAULT, SKL_PARAM_INIT,
+ *                              SKL_PARAM_SET, SKL_PARAM_BIND
+ *
+ * %SKL_TKN_U32_MOD_PARAM_ID:   ID of the module params
+ *
+ * %SKL_TKN_U32_CAPS_SET_PARAMS:
+ *                              Set params value
+ *
+ * %SKL_TKN_U32_CAPS_PARAMS_ID: Params ID
+ *
+ * %SKL_TKN_U32_CAPS_SIZE:      Caps size
+ *
+ * %SKL_TKN_U32_PROC_DOMAIN:    Specify processing domain
+ *
+ * module_id and loadable flags dont have tokens as these values will be
+ * read from the DSP FW manifest
+ */
+enum SKL_TKNS {
+	SKL_TKN_UUID = 1,
+	SKL_TKN_U8_NUM_BLOCKS,
+	SKL_TKN_U8_BLOCK_TYPE,
+	SKL_TKN_U8_IN_PIN_TYPE,
+	SKL_TKN_U8_OUT_PIN_TYPE,
+	SKL_TKN_U8_DYN_IN_PIN,
+	SKL_TKN_U8_DYN_OUT_PIN,
+	SKL_TKN_U8_IN_QUEUE_COUNT,
+	SKL_TKN_U8_OUT_QUEUE_COUNT,
+	SKL_TKN_U8_TIME_SLOT,
+	SKL_TKN_U8_CORE_ID,
+	SKL_TKN_U8_MOD_TYPE,
+	SKL_TKN_U8_CONN_TYPE,
+	SKL_TKN_U8_DEV_TYPE,
+	SKL_TKN_U8_HW_CONN_TYPE,
+	SKL_TKN_U16_MOD_INST_ID,
+	SKL_TKN_U16_BLOCK_SIZE,
+	SKL_TKN_U32_MAX_MCPS,
+	SKL_TKN_U32_MEM_PAGES,
+	SKL_TKN_U32_OBS,
+	SKL_TKN_U32_IBS,
+	SKL_TKN_U32_VBUS_ID,
+	SKL_TKN_U32_PARAMS_FIXUP,
+	SKL_TKN_U32_CONVERTER,
+	SKL_TKN_U32_PIPE_ID,
+	SKL_TKN_U32_PIPE_CONN_TYPE,
+	SKL_TKN_U32_PIPE_PRIORITY,
+	SKL_TKN_U32_PIPE_MEM_PGS,
+	SKL_TKN_U32_DIR_PIN_COUNT,
+	SKL_TKN_U32_FMT_CH,
+	SKL_TKN_U32_FMT_FREQ,
+	SKL_TKN_U32_FMT_BIT_DEPTH,
+	SKL_TKN_U32_FMT_SAMPLE_SIZE,
+	SKL_TKN_U32_FMT_CH_CONFIG,
+	SKL_TKN_U32_FMT_INTERLEAVE,
+	SKL_TKN_U32_FMT_SAMPLE_TYPE,
+	SKL_TKN_U32_FMT_CH_MAP,
+	SKL_TKN_U32_PIN_MOD_ID,
+	SKL_TKN_U32_PIN_INST_ID,
+	SKL_TKN_U32_MOD_SET_PARAMS,
+	SKL_TKN_U32_MOD_PARAM_ID,
+	SKL_TKN_U32_CAPS_SET_PARAMS,
+	SKL_TKN_U32_CAPS_PARAMS_ID,
+	SKL_TKN_U32_CAPS_SIZE,
+	SKL_TKN_U32_PROC_DOMAIN,
+	SKL_TKN_MAX = SKL_TKN_U32_PROC_DOMAIN,
+};
+
+#endif
-- 
2.8.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH 4/4] ASoC: Intel: Skylake: Parse manifest data
  2016-08-22 17:47   ` Mark Brown
@ 2016-08-23  4:02     ` Vinod Koul
  0 siblings, 0 replies; 15+ messages in thread
From: Vinod Koul @ 2016-08-23  4:02 UTC (permalink / raw)
  To: Mark Brown; +Cc: liam.r.girdwood, patches.audio, alsa-devel, Shreyas NC


[-- Attachment #1.1: Type: text/plain, Size: 637 bytes --]

On Mon, Aug 22, 2016 at 06:47:14PM +0100, Mark Brown wrote:
> On Fri, Aug 12, 2016 at 12:29:53PM +0530, Vinod Koul wrote:
> > From: Shreyas NC <shreyas.nc@intel.com>
> > 
> > Topology manifest has lib names and lib count info. So,
> > define tokens to represent module private data and parse
> > these tokens to fill up the manifest structure in the driver
> > accordingly.
> 
> This doesn't apply against current code, please check and resend.

Surpised about that. I typically send againt your topic/intel.
Any other changes merged shouldn't have conflicted.

I have reapplied and sent again now.

Thanks
-- 
~Vinod

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2016-08-23  3:54 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-12  6:59 [PATCH 0/4] ASoC: Intel: Skylake: Add token support for topology data Vinod Koul
2016-08-12  6:59 ` [PATCH 1/4] ASoC: uapi: Intel: Skylake: Define vendor specific tokens Vinod Koul
2016-08-22 17:59   ` Applied "ASoC: uapi: Intel: Skylake: Define vendor specific tokens" to the asoc tree Mark Brown
2016-08-12  6:59 ` [PATCH 2/4] ASoC: Intel: Skylake: Parse vendor tokens to build module data Vinod Koul
2016-08-22 17:59   ` Applied "ASoC: Intel: Skylake: Parse vendor tokens to build module data" to the asoc tree Mark Brown
2016-08-12  6:59 ` [PATCH 3/4] ASoC: Intel: Skylake: Remove dfw config and associated structures Vinod Koul
2016-08-22 17:59   ` Applied "ASoC: Intel: Skylake: Remove dfw config and associated structures" to the asoc tree Mark Brown
2016-08-12  6:59 ` [PATCH 4/4] ASoC: Intel: Skylake: Parse manifest data Vinod Koul
2016-08-22 17:47   ` Mark Brown
2016-08-23  4:02     ` Vinod Koul
2016-08-12 10:41 ` [PATCH 0/4] ASoC: Intel: Skylake: Add token support for topology data Mark Brown
2016-08-12 10:55   ` Vinod Koul
2016-08-17  6:59     ` Mengdong Lin
2016-08-17 10:01       ` Mark Brown
2016-08-17 15:03         ` Lin, Mengdong

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.