summaryrefslogtreecommitdiff
path: root/sound/soc/intel/avs/path.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/intel/avs/path.c')
-rw-r--r--sound/soc/intel/avs/path.c80
1 files changed, 55 insertions, 25 deletions
diff --git a/sound/soc/intel/avs/path.c b/sound/soc/intel/avs/path.c
index 3aa16ee8d34c..f31d5e2caa7b 100644
--- a/sound/soc/intel/avs/path.c
+++ b/sound/soc/intel/avs/path.c
@@ -1,12 +1,13 @@
// SPDX-License-Identifier: GPL-2.0-only
//
-// Copyright(c) 2021 Intel Corporation. All rights reserved.
+// Copyright(c) 2021 Intel Corporation
//
// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
//
-#include <sound/intel-nhlt.h>
+#include <linux/acpi.h>
+#include <acpi/nhlt.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include "avs.h"
@@ -143,16 +144,17 @@ static bool avs_dma_type_is_input(u32 dma_type)
static int avs_copier_create(struct avs_dev *adev, struct avs_path_module *mod)
{
- struct nhlt_acpi_table *nhlt = adev->nhlt;
struct avs_tplg_module *t = mod->template;
struct avs_copier_cfg *cfg;
- struct nhlt_specific_cfg *ep_blob;
+ struct acpi_nhlt_format_config *ep_blob;
+ struct acpi_nhlt_endpoint *ep;
union avs_connector_node_id node_id = {0};
- size_t cfg_size, data_size = 0;
+ size_t cfg_size, data_size;
void *data = NULL;
u32 dma_type;
int ret;
+ data_size = sizeof(cfg->gtw_cfg.config);
dma_type = t->cfg_ext->copier.dma_type;
node_id.dma_type = dma_type;
@@ -174,18 +176,18 @@ static int avs_copier_create(struct avs_dev *adev, struct avs_path_module *mod)
else
fmt = t->cfg_ext->copier.out_fmt;
- ep_blob = intel_nhlt_get_endpoint_blob(adev->dev,
- nhlt, t->cfg_ext->copier.vindex.i2s.instance,
- NHLT_LINK_SSP, fmt->valid_bit_depth, fmt->bit_depth,
- fmt->num_channels, fmt->sampling_freq, direction,
- NHLT_DEVICE_I2S);
+ ep = acpi_nhlt_find_endpoint(ACPI_NHLT_LINKTYPE_SSP,
+ ACPI_NHLT_DEVICETYPE_CODEC, direction,
+ t->cfg_ext->copier.vindex.i2s.instance);
+ ep_blob = acpi_nhlt_endpoint_find_fmtcfg(ep, fmt->num_channels, fmt->sampling_freq,
+ fmt->valid_bit_depth, fmt->bit_depth);
if (!ep_blob) {
dev_err(adev->dev, "no I2S ep_blob found\n");
return -ENOENT;
}
- data = ep_blob->caps;
- data_size = ep_blob->size;
+ data = ep_blob->config.capabilities;
+ data_size = ep_blob->config.capabilities_size;
/* I2S gateway's vindex is statically assigned in topology */
node_id.vindex = t->cfg_ext->copier.vindex.val;
@@ -199,17 +201,16 @@ static int avs_copier_create(struct avs_dev *adev, struct avs_path_module *mod)
else
fmt = t->in_fmt;
- ep_blob = intel_nhlt_get_endpoint_blob(adev->dev, nhlt, 0,
- NHLT_LINK_DMIC, fmt->valid_bit_depth,
- fmt->bit_depth, fmt->num_channels,
- fmt->sampling_freq, direction, NHLT_DEVICE_DMIC);
+ ep = acpi_nhlt_find_endpoint(ACPI_NHLT_LINKTYPE_PDM, -1, direction, 0);
+ ep_blob = acpi_nhlt_endpoint_find_fmtcfg(ep, fmt->num_channels, fmt->sampling_freq,
+ fmt->valid_bit_depth, fmt->bit_depth);
if (!ep_blob) {
dev_err(adev->dev, "no DMIC ep_blob found\n");
return -ENOENT;
}
- data = ep_blob->caps;
- data_size = ep_blob->size;
+ data = ep_blob->config.capabilities;
+ data_size = ep_blob->config.capabilities_size;
/* DMIC gateway's vindex is statically assigned in topology */
node_id.vindex = t->cfg_ext->copier.vindex.val;
@@ -233,10 +234,7 @@ static int avs_copier_create(struct avs_dev *adev, struct avs_path_module *mod)
break;
}
- cfg_size = sizeof(*cfg) + data_size;
- /* Every config-BLOB contains gateway attributes. */
- if (data_size)
- cfg_size -= sizeof(cfg->gtw_cfg.config.attrs);
+ cfg_size = offsetof(struct avs_copier_cfg, gtw_cfg.config) + data_size;
if (cfg_size > AVS_MAILBOX_SIZE)
return -EINVAL;
@@ -254,7 +252,7 @@ static int avs_copier_create(struct avs_dev *adev, struct avs_path_module *mod)
/* config_length in DWORDs */
cfg->gtw_cfg.config_length = DIV_ROUND_UP(data_size, 4);
if (data)
- memcpy(&cfg->gtw_cfg.config, data, data_size);
+ memcpy(&cfg->gtw_cfg.config.blob, data, data_size);
mod->gtw_attrs = cfg->gtw_cfg.config.attrs;
@@ -367,6 +365,7 @@ static int avs_asrc_create(struct avs_dev *adev, struct avs_path_module *mod)
struct avs_tplg_module *t = mod->template;
struct avs_asrc_cfg cfg;
+ memset(&cfg, 0, sizeof(cfg));
cfg.base.cpc = t->cfg_base->cpc;
cfg.base.ibs = t->cfg_base->ibs;
cfg.base.obs = t->cfg_base->obs;
@@ -547,6 +546,33 @@ static int avs_path_module_type_create(struct avs_dev *adev, struct avs_path_mod
return avs_modext_create(adev, mod);
}
+static int avs_path_module_send_init_configs(struct avs_dev *adev, struct avs_path_module *mod)
+{
+ struct avs_soc_component *acomp;
+
+ acomp = to_avs_soc_component(mod->template->owner->owner->owner->owner->comp);
+
+ u32 num_ids = mod->template->num_config_ids;
+ u32 *ids = mod->template->config_ids;
+
+ for (int i = 0; i < num_ids; i++) {
+ struct avs_tplg_init_config *config = &acomp->tplg->init_configs[ids[i]];
+ size_t len = config->length;
+ void *data = config->data;
+ u32 param = config->param;
+ int ret;
+
+ ret = avs_ipc_set_large_config(adev, mod->module_id, mod->instance_id,
+ param, data, len);
+ if (ret) {
+ dev_err(adev->dev, "send initial module config failed: %d\n", ret);
+ return AVS_IPC_RET(ret);
+ }
+ }
+
+ return 0;
+}
+
static void avs_path_module_free(struct avs_dev *adev, struct avs_path_module *mod)
{
kfree(mod);
@@ -580,6 +606,12 @@ avs_path_module_create(struct avs_dev *adev,
return ERR_PTR(ret);
}
+ ret = avs_path_module_send_init_configs(adev, mod);
+ if (ret) {
+ kfree(mod);
+ return ERR_PTR(ret);
+ }
+
return mod;
}
@@ -677,8 +709,6 @@ static int avs_path_pipeline_arm(struct avs_dev *adev,
/* bind current module to next module on list */
source = mod;
sink = list_next_entry(mod, node);
- if (!source || !sink)
- return -EINVAL;
ret = avs_ipc_bind(adev, source->module_id, source->instance_id,
sink->module_id, sink->instance_id, 0, 0);