diff options
author | Mark Brown <broonie@kernel.org> | 2017-02-19 16:35:45 +0000 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2017-02-19 16:35:45 +0000 |
commit | 16b5711485b0eba250451b3a85ab869939f20c7d (patch) | |
tree | 16856f74dc4e978af2c018125b7a47e443621476 /sound/soc/intel/skylake/skl-topology.c | |
parent | c7bb6d8060eec4f3806b88796fbf46db1e73d900 (diff) | |
parent | 7ba8ba3f4f9604ce776475e3b501e41c762af797 (diff) |
Merge remote-tracking branch 'asoc/topic/intel' into asoc-next
Diffstat (limited to 'sound/soc/intel/skylake/skl-topology.c')
-rw-r--r-- | sound/soc/intel/skylake/skl-topology.c | 97 |
1 files changed, 71 insertions, 26 deletions
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index bd313c907b20..ed58b5b3555a 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -330,6 +330,31 @@ static void skl_tplg_update_buffer_size(struct skl_sst *ctx, multiplier; } +static u8 skl_tplg_be_dev_type(int dev_type) +{ + int ret; + + switch (dev_type) { + case SKL_DEVICE_BT: + ret = NHLT_DEVICE_BT; + break; + + case SKL_DEVICE_DMIC: + ret = NHLT_DEVICE_DMIC; + break; + + case SKL_DEVICE_I2S: + ret = NHLT_DEVICE_I2S; + break; + + default: + ret = NHLT_DEVICE_INVALID; + break; + } + + return ret; +} + static int skl_tplg_update_be_blob(struct snd_soc_dapm_widget *w, struct skl_sst *ctx) { @@ -338,6 +363,7 @@ static int skl_tplg_update_be_blob(struct snd_soc_dapm_widget *w, u32 ch, s_freq, s_fmt; struct nhlt_specific_cfg *cfg; struct skl *skl = get_skl_ctx(ctx->dev); + u8 dev_type = skl_tplg_be_dev_type(m_cfg->dev_type); /* check if we already have blob */ if (m_cfg->formats_config.caps_size > 0) @@ -374,7 +400,7 @@ static int skl_tplg_update_be_blob(struct snd_soc_dapm_widget *w, /* update the blob based on virtual bus_id and default params */ cfg = skl_get_ep_blob(skl, m_cfg->vbus_id, link_type, - s_fmt, ch, s_freq, dir); + s_fmt, ch, s_freq, dir, dev_type); if (cfg) { m_cfg->formats_config.caps_size = cfg->size; m_cfg->formats_config.caps = (u32 *) &cfg->caps; @@ -496,6 +522,20 @@ static int skl_tplg_set_module_init_data(struct snd_soc_dapm_widget *w) return 0; } +static int skl_tplg_module_prepare(struct skl_sst *ctx, struct skl_pipe *pipe, + struct snd_soc_dapm_widget *w, struct skl_module_cfg *mcfg) +{ + switch (mcfg->dev_type) { + case SKL_DEVICE_HDAHOST: + return skl_pcm_host_dma_prepare(ctx->dev, pipe->p_params); + + case SKL_DEVICE_HDALINK: + return skl_pcm_link_dma_prepare(ctx->dev, pipe->p_params); + } + + return 0; +} + /* * Inside a pipe instance, we can have various modules. These modules need * to instantiated in DSP by invoking INIT_MODULE IPC, which is achieved by @@ -535,6 +575,11 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe) mconfig->m_state = SKL_MODULE_LOADED; } + /* prepare the DMA if the module is gateway cpr */ + ret = skl_tplg_module_prepare(ctx, pipe, w, mconfig); + if (ret < 0) + return ret; + /* update blob if blob is null for be with default value */ skl_tplg_update_be_blob(w, ctx); @@ -974,7 +1019,6 @@ static int skl_tplg_mixer_dapm_post_pmd_event(struct snd_soc_dapm_widget *w, struct skl_module_cfg *src_module = NULL, *dst_module; struct skl_sst *ctx = skl->skl_sst; struct skl_pipe *s_pipe = mconfig->pipe; - int ret = 0; if (s_pipe->state == SKL_PIPE_INVALID) return -EINVAL; @@ -996,7 +1040,7 @@ static int skl_tplg_mixer_dapm_post_pmd_event(struct snd_soc_dapm_widget *w, src_module = dst_module; } - ret = skl_delete_pipe(ctx, mconfig->pipe); + skl_delete_pipe(ctx, mconfig->pipe); return skl_tplg_unload_pipe_modules(ctx, s_pipe); } @@ -1207,6 +1251,7 @@ static void skl_tplg_fill_dma_id(struct skl_module_cfg *mcfg, switch (mcfg->dev_type) { case SKL_DEVICE_HDALINK: pipe->p_params->link_dma_id = params->link_dma_id; + pipe->p_params->link_index = params->link_index; break; case SKL_DEVICE_HDAHOST: @@ -1220,6 +1265,7 @@ static void skl_tplg_fill_dma_id(struct skl_module_cfg *mcfg, pipe->p_params->ch = params->ch; pipe->p_params->s_freq = params->s_freq; pipe->p_params->stream = params->stream; + pipe->p_params->format = params->format; } else { memcpy(pipe->p_params, params, sizeof(*params)); @@ -1428,6 +1474,7 @@ static int skl_tplg_be_fill_pipe_params(struct snd_soc_dai *dai, struct nhlt_specific_cfg *cfg; struct skl *skl = get_skl_ctx(dai->dev); int link_type = skl_tplg_be_link_type(mconfig->dev_type); + u8 dev_type = skl_tplg_be_dev_type(mconfig->dev_type); skl_tplg_fill_dma_id(mconfig, params); @@ -1437,7 +1484,8 @@ static int skl_tplg_be_fill_pipe_params(struct snd_soc_dai *dai, /* update the blob based on virtual bus_id*/ cfg = skl_get_ep_blob(skl, mconfig->vbus_id, link_type, params->s_fmt, params->ch, - params->s_freq, params->stream); + params->s_freq, params->stream, + dev_type); if (cfg) { mconfig->formats_config.caps_size = cfg->size; mconfig->formats_config.caps = (u32 *) &cfg->caps; @@ -2280,20 +2328,21 @@ static int skl_tplg_control_load(struct snd_soc_component *cmpnt, 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) + struct skl *skl) { 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) { + if (ref_count > skl->skl_sst->lib_count - 1) { ref_count = 0; return -EINVAL; } - strncpy(minfo->lib[ref_count].name, str_elem->string, - ARRAY_SIZE(minfo->lib[ref_count].name)); + strncpy(skl->skl_sst->lib_info[ref_count].name, + str_elem->string, + ARRAY_SIZE(skl->skl_sst->lib_info[ref_count].name)); ref_count++; tkn_count++; break; @@ -2308,14 +2357,14 @@ static int skl_tplg_fill_str_mfest_tkn(struct device *dev, static int skl_tplg_get_str_tkn(struct device *dev, struct snd_soc_tplg_vendor_array *array, - struct skl_dfw_manifest *minfo) + struct skl *skl) { 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); + ret = skl_tplg_fill_str_mfest_tkn(dev, str_elem, skl); str_elem++; if (ret < 0) @@ -2329,13 +2378,13 @@ static int skl_tplg_get_str_tkn(struct device *dev, static int skl_tplg_get_int_tkn(struct device *dev, struct snd_soc_tplg_vendor_value_elem *tkn_elem, - struct skl_dfw_manifest *minfo) + struct skl *skl) { int tkn_count = 0; switch (tkn_elem->token) { case SKL_TKN_U32_LIB_COUNT: - minfo->lib_count = tkn_elem->value; + skl->skl_sst->lib_count = tkn_elem->value; tkn_count++; break; @@ -2352,7 +2401,7 @@ static int skl_tplg_get_int_tkn(struct device *dev, * type. */ static int skl_tplg_get_manifest_tkn(struct device *dev, - char *pvt_data, struct skl_dfw_manifest *minfo, + char *pvt_data, struct skl *skl, int block_size) { int tkn_count = 0, ret; @@ -2368,7 +2417,7 @@ static int skl_tplg_get_manifest_tkn(struct device *dev, off += array->size; switch (array->type) { case SND_SOC_TPLG_TUPLE_TYPE_STRING: - ret = skl_tplg_get_str_tkn(dev, array, minfo); + ret = skl_tplg_get_str_tkn(dev, array, skl); if (ret < 0) return ret; @@ -2390,7 +2439,7 @@ static int skl_tplg_get_manifest_tkn(struct device *dev, while (tkn_count <= array->num_elems - 1) { ret = skl_tplg_get_int_tkn(dev, - tkn_elem, minfo); + tkn_elem, skl); if (ret < 0) return ret; @@ -2411,7 +2460,7 @@ static int skl_tplg_get_manifest_tkn(struct device *dev, * 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 device *dev, struct skl *skl) { struct snd_soc_tplg_vendor_array *array; int num_blocks, block_size = 0, block_type, off = 0; @@ -2454,7 +2503,7 @@ static int skl_tplg_get_manifest_data(struct snd_soc_tplg_manifest *manifest, data = (manifest->priv.data + off); if (block_type == SKL_TYPE_TUPLE) { - ret = skl_tplg_get_manifest_tkn(dev, data, minfo, + ret = skl_tplg_get_manifest_tkn(dev, data, skl, block_size); if (ret < 0) @@ -2472,27 +2521,23 @@ static int skl_tplg_get_manifest_data(struct snd_soc_tplg_manifest *manifest, static int skl_manifest_load(struct snd_soc_component *cmpnt, struct snd_soc_tplg_manifest *manifest) { - struct skl_dfw_manifest *minfo; struct hdac_ext_bus *ebus = snd_soc_component_get_drvdata(cmpnt); struct hdac_bus *bus = ebus_to_hbus(ebus); struct skl *skl = ebus_to_skl(ebus); - int ret = 0; /* proceed only if we have private data defined */ if (manifest->priv.size == 0) return 0; - minfo = &skl->skl_sst->manifest; - - skl_tplg_get_manifest_data(manifest, bus->dev, minfo); + skl_tplg_get_manifest_data(manifest, bus->dev, skl); - if (minfo->lib_count > HDA_MAX_LIB) { + if (skl->skl_sst->lib_count > SKL_MAX_LIB) { dev_err(bus->dev, "Exceeding max Library count. Got:%d\n", - minfo->lib_count); - ret = -EINVAL; + skl->skl_sst->lib_count); + return -EINVAL; } - return ret; + return 0; } static struct snd_soc_tplg_ops skl_tplg_ops = { |