Commit 6f02c089 authored by Mark Brown's avatar Mark Brown

Merge series "ASoC: Intel: Skylake: Fix and support complex" from Cezary...

Merge series "ASoC: Intel: Skylake: Fix and support complex" from Cezary Rojewski <cezary.rojewski@intel.com>:

Existing skylake-driver supports very basic scenarios with limited range
of modules and their control. Attached changes first fix code as several
advanced configurations are 'mentioned' throughout the files but are not
actually functional. Follow up are changes adding missing support for
said configurations.

Cezary Rojewski (5):
  ASoC: Intel: kbl_da7219_max98927: Fix format selection for max98373
  ASoC: Intel: Skylake: Leave data as is when invoking TLV IPCs
  ASoC: Intel: Skylake: Fix module resource and format selection
  ASoC: Intel: Skylake: Fix module configuration for KPB and MIXER
  ASoC: Intel: Skylake: Select first entry for singular pipe config
    arrays

Gustaw Lewandowski (2):
  ASoC: Intel: Skylake: Fix passing loadable flag for module
  ASoC: Intel: Skylake: Simplify m_state for loadable modules

Kareem Shaik (1):
  ASoC: Intel: Skylake: Support multiple format configs

Pawel Harlozinski (1):
  ASoC: Intel: Skylake: Properly configure modules with generic
    extension

Piotr Maziarz (1):
  ASoC: Intel: Skylake: Select proper format for NHLT blob

Szymon Mielczarek (1):
  ASoC: Intel: Skylake: Support modules with generic extension

 include/uapi/sound/snd_sst_tokens.h          |   6 +-
 sound/soc/intel/boards/kbl_da7219_max98927.c |  55 +------
 sound/soc/intel/skylake/skl-messages.c       | 155 ++++++++++++-------
 sound/soc/intel/skylake/skl-pcm.c            |  25 ++-
 sound/soc/intel/skylake/skl-topology.c       | 155 +++++++++++--------
 sound/soc/intel/skylake/skl-topology.h       |  26 +++-
 6 files changed, 231 insertions(+), 191 deletions(-)

--
2.25.1
parents d019403a b947d2b4
......@@ -233,6 +233,8 @@
*
* %SKL_TKN_U32_ASTATE_CLK_SRC: Clock source for A-State entry
*
* %SKL_TKN_U32_FMT_CFG_IDX: Format config index
*
* module_id and loadable flags dont have tokens as these values will be
* read from the DSP FW manifest
*
......@@ -324,7 +326,9 @@ enum SKL_TKNS {
SKL_TKN_U32_ASTATE_COUNT,
SKL_TKN_U32_ASTATE_KCPS,
SKL_TKN_U32_ASTATE_CLK_SRC,
SKL_TKN_MAX = SKL_TKN_U32_ASTATE_CLK_SRC,
SKL_TKN_U32_FMT_CFG_IDX = 96,
SKL_TKN_MAX = SKL_TKN_U32_FMT_CFG_IDX,
};
#endif
......@@ -199,7 +199,7 @@ static int kabylake_ssp0_hw_params(struct snd_pcm_substream *substream,
}
if (!strcmp(codec_dai->component->name, MAX98373_DEV0_NAME)) {
ret = snd_soc_dai_set_tdm_slot(codec_dai,
0x03, 3, 8, 24);
0x30, 3, 8, 16);
if (ret < 0) {
dev_err(runtime->dev,
"DEV0 TDM slot err:%d\n", ret);
......@@ -208,10 +208,10 @@ static int kabylake_ssp0_hw_params(struct snd_pcm_substream *substream,
}
if (!strcmp(codec_dai->component->name, MAX98373_DEV1_NAME)) {
ret = snd_soc_dai_set_tdm_slot(codec_dai,
0x0C, 3, 8, 24);
0xC0, 3, 8, 16);
if (ret < 0) {
dev_err(runtime->dev,
"DEV0 TDM slot err:%d\n", ret);
"DEV1 TDM slot err:%d\n", ret);
return ret;
}
}
......@@ -311,24 +311,6 @@ static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
* The above 2 loops are mutually exclusive based on the stream direction,
* thus rtd_dpcm variable will never be overwritten
*/
/*
* Topology for kblda7219m98373 & kblmax98373 supports only S24_LE,
* where as kblda7219m98927 & kblmax98927 supports S16_LE by default.
* Skipping the port wise FE and BE configuration for kblda7219m98373 &
* kblmax98373 as the topology (FE & BE) supports S24_LE only.
*/
if (!strcmp(rtd->card->name, "kblda7219m98373") ||
!strcmp(rtd->card->name, "kblmax98373")) {
/* The ADSP will convert the FE rate to 48k, stereo */
rate->min = rate->max = 48000;
chan->min = chan->max = DUAL_CHANNEL;
/* set SSP to 24 bit */
snd_mask_none(fmt);
snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE);
return 0;
}
/*
* The ADSP will convert the FE rate to 48k, stereo, 24 bit
......@@ -479,31 +461,20 @@ static struct snd_pcm_hw_constraint_list constraints_channels_quad = {
static int kbl_fe_startup(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_soc_pcm_runtime *soc_rt = asoc_substream_to_rtd(substream);
/*
* On this platform for PCM device we support,
* 48Khz
* stereo
* 16 bit audio
*/
runtime->hw.channels_max = DUAL_CHANNEL;
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
&constraints_channels);
/*
* Setup S24_LE (32 bit container and 24 bit valid data) for
* kblda7219m98373 & kblmax98373. For kblda7219m98927 &
* kblmax98927 keeping it as 16/16 due to topology FW dependency.
*/
if (!strcmp(soc_rt->card->name, "kblda7219m98373") ||
!strcmp(soc_rt->card->name, "kblmax98373")) {
runtime->hw.formats = SNDRV_PCM_FMTBIT_S24_LE;
snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
} else {
runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
}
runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
snd_pcm_hw_constraint_list(runtime, 0,
SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
......@@ -536,23 +507,11 @@ static int kabylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
static int kabylake_dmic_startup(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_soc_pcm_runtime *soc_rt = asoc_substream_to_rtd(substream);
runtime->hw.channels_min = runtime->hw.channels_max = QUAD_CHANNEL;
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
&constraints_channels_quad);
/*
* Topology for kblda7219m98373 & kblmax98373 supports only S24_LE.
* The DMIC also configured for S24_LE. Forcing the DMIC format to
* S24_LE due to the topology FW dependency.
*/
if (!strcmp(soc_rt->card->name, "kblda7219m98373") ||
!strcmp(soc_rt->card->name, "kblmax98373")) {
runtime->hw.formats = SNDRV_PCM_FMTBIT_S24_LE;
snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
}
return snd_pcm_hw_constraint_list(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
}
......
......@@ -472,6 +472,75 @@ static void skl_set_base_module_format(struct skl_dev *skl,
base_cfg->is_pages = res->is_pages;
}
static void fill_pin_params(struct skl_audio_data_format *pin_fmt,
struct skl_module_fmt *format)
{
pin_fmt->number_of_channels = format->channels;
pin_fmt->s_freq = format->s_freq;
pin_fmt->bit_depth = format->bit_depth;
pin_fmt->valid_bit_depth = format->valid_bit_depth;
pin_fmt->ch_cfg = format->ch_cfg;
pin_fmt->sample_type = format->sample_type;
pin_fmt->channel_map = format->ch_map;
pin_fmt->interleaving = format->interleaving_style;
}
/*
* Any module configuration begins with a base module configuration but
* can be followed by a generic extension containing audio format for all
* module's pins that are in use.
*/
static void skl_set_base_ext_module_format(struct skl_dev *skl,
struct skl_module_cfg *mconfig,
struct skl_base_cfg_ext *base_cfg_ext)
{
struct skl_module *module = mconfig->module;
struct skl_module_pin_resources *pin_res;
struct skl_module_iface *fmt = &module->formats[mconfig->fmt_idx];
struct skl_module_res *res = &module->resources[mconfig->res_idx];
struct skl_module_fmt *format;
struct skl_pin_format *pin_fmt;
char *params;
int i;
base_cfg_ext->nr_input_pins = res->nr_input_pins;
base_cfg_ext->nr_output_pins = res->nr_output_pins;
base_cfg_ext->priv_param_length =
mconfig->formats_config[SKL_PARAM_INIT].caps_size;
for (i = 0; i < res->nr_input_pins; i++) {
pin_res = &res->input[i];
pin_fmt = &base_cfg_ext->pins_fmt[i];
pin_fmt->pin_idx = pin_res->pin_index;
pin_fmt->buf_size = pin_res->buf_size;
format = &fmt->inputs[pin_res->pin_index].fmt;
fill_pin_params(&pin_fmt->audio_fmt, format);
}
for (i = 0; i < res->nr_output_pins; i++) {
pin_res = &res->output[i];
pin_fmt = &base_cfg_ext->pins_fmt[res->nr_input_pins + i];
pin_fmt->pin_idx = pin_res->pin_index;
pin_fmt->buf_size = pin_res->buf_size;
format = &fmt->outputs[pin_res->pin_index].fmt;
fill_pin_params(&pin_fmt->audio_fmt, format);
}
if (!base_cfg_ext->priv_param_length)
return;
params = (char *)base_cfg_ext + sizeof(struct skl_base_cfg_ext);
params += (base_cfg_ext->nr_input_pins + base_cfg_ext->nr_output_pins) *
sizeof(struct skl_pin_format);
memcpy(params, mconfig->formats_config[SKL_PARAM_INIT].caps,
mconfig->formats_config[SKL_PARAM_INIT].caps_size);
}
/*
* Copies copier capabilities into copier module and updates copier module
* config size.
......@@ -479,15 +548,15 @@ static void skl_set_base_module_format(struct skl_dev *skl,
static void skl_copy_copier_caps(struct skl_module_cfg *mconfig,
struct skl_cpr_cfg *cpr_mconfig)
{
if (mconfig->formats_config.caps_size == 0)
if (mconfig->formats_config[SKL_PARAM_INIT].caps_size == 0)
return;
memcpy(cpr_mconfig->gtw_cfg.config_data,
mconfig->formats_config.caps,
mconfig->formats_config.caps_size);
mconfig->formats_config[SKL_PARAM_INIT].caps,
mconfig->formats_config[SKL_PARAM_INIT].caps_size);
cpr_mconfig->gtw_cfg.config_length =
(mconfig->formats_config.caps_size) / 4;
(mconfig->formats_config[SKL_PARAM_INIT].caps_size) / 4;
}
#define SKL_NON_GATEWAY_CPR_NODE_ID 0xFFFFFFFF
......@@ -737,28 +806,6 @@ static void skl_set_copier_format(struct skl_dev *skl,
skl_setup_cpr_gateway_cfg(skl, mconfig, cpr_mconfig);
}
/*
* Algo module are DSP pre processing modules. Algo module take base module
* configuration and params
*/
static void skl_set_algo_format(struct skl_dev *skl,
struct skl_module_cfg *mconfig,
struct skl_algo_cfg *algo_mcfg)
{
struct skl_base_cfg *base_cfg = (struct skl_base_cfg *)algo_mcfg;
skl_set_base_module_format(skl, mconfig, base_cfg);
if (mconfig->formats_config.caps_size == 0)
return;
memcpy(algo_mcfg->params,
mconfig->formats_config.caps,
mconfig->formats_config.caps_size);
}
/*
* Mic select module allows selecting one or many input channels, thus
* acting as a demux.
......@@ -781,12 +828,14 @@ static void skl_set_base_outfmt_format(struct skl_dev *skl,
static u16 skl_get_module_param_size(struct skl_dev *skl,
struct skl_module_cfg *mconfig)
{
struct skl_module_res *res;
struct skl_module *module = mconfig->module;
u16 param_size;
switch (mconfig->m_type) {
case SKL_MODULE_TYPE_COPIER:
param_size = sizeof(struct skl_cpr_cfg);
param_size += mconfig->formats_config.caps_size;
param_size += mconfig->formats_config[SKL_PARAM_INIT].caps_size;
return param_size;
case SKL_MODULE_TYPE_SRCINT:
......@@ -795,22 +844,24 @@ static u16 skl_get_module_param_size(struct skl_dev *skl,
case SKL_MODULE_TYPE_UPDWMIX:
return sizeof(struct skl_up_down_mixer_cfg);
case SKL_MODULE_TYPE_ALGO:
param_size = sizeof(struct skl_base_cfg);
param_size += mconfig->formats_config.caps_size;
return param_size;
case SKL_MODULE_TYPE_BASE_OUTFMT:
case SKL_MODULE_TYPE_MIC_SELECT:
case SKL_MODULE_TYPE_KPB:
return sizeof(struct skl_base_outfmt_cfg);
default:
/*
* return only base cfg when no specific module type is
* specified
*/
case SKL_MODULE_TYPE_MIXER:
case SKL_MODULE_TYPE_KPB:
return sizeof(struct skl_base_cfg);
case SKL_MODULE_TYPE_ALGO:
default:
res = &module->resources[mconfig->res_idx];
param_size = sizeof(struct skl_base_cfg) + sizeof(struct skl_base_cfg_ext);
param_size += (res->nr_input_pins + res->nr_output_pins) *
sizeof(struct skl_pin_format);
param_size += mconfig->formats_config[SKL_PARAM_INIT].caps_size;
return param_size;
}
return 0;
......@@ -851,20 +902,23 @@ static int skl_set_module_format(struct skl_dev *skl,
skl_set_updown_mixer_format(skl, module_config, *param_data);
break;
case SKL_MODULE_TYPE_ALGO:
skl_set_algo_format(skl, module_config, *param_data);
break;
case SKL_MODULE_TYPE_BASE_OUTFMT:
case SKL_MODULE_TYPE_MIC_SELECT:
case SKL_MODULE_TYPE_KPB:
skl_set_base_outfmt_format(skl, module_config, *param_data);
break;
default:
case SKL_MODULE_TYPE_MIXER:
case SKL_MODULE_TYPE_KPB:
skl_set_base_module_format(skl, module_config, *param_data);
break;
case SKL_MODULE_TYPE_ALGO:
default:
skl_set_base_module_format(skl, module_config, *param_data);
skl_set_base_ext_module_format(skl, module_config,
*param_data +
sizeof(struct skl_base_cfg));
break;
}
dev_dbg(skl->dev, "Module type=%d id=%d config size: %d bytes\n",
......@@ -1085,19 +1139,6 @@ int skl_unbind_modules(struct skl_dev *skl,
return ret;
}
static void fill_pin_params(struct skl_audio_data_format *pin_fmt,
struct skl_module_fmt *format)
{
pin_fmt->number_of_channels = format->channels;
pin_fmt->s_freq = format->s_freq;
pin_fmt->bit_depth = format->bit_depth;
pin_fmt->valid_bit_depth = format->valid_bit_depth;
pin_fmt->ch_cfg = format->ch_cfg;
pin_fmt->sample_type = format->sample_type;
pin_fmt->channel_map = format->ch_map;
pin_fmt->interleaving = format->interleaving_style;
}
#define CPR_SINK_FMT_PARAM_ID 2
/*
......
......@@ -1310,21 +1310,6 @@ static int skl_get_module_info(struct skl_dev *skl,
return -EIO;
}
list_for_each_entry(module, &skl->uuid_list, list) {
if (guid_equal(uuid_mod, &module->uuid)) {
mconfig->id.module_id = module->id;
if (mconfig->module)
mconfig->module->loadable = module->is_loadable;
ret = 0;
break;
}
}
if (ret)
return ret;
uuid_mod = &module->uuid;
ret = -EIO;
for (i = 0; i < skl->nr_modules; i++) {
skl_module = skl->modules[i];
uuid_tplg = &skl_module->uuid;
......@@ -1334,10 +1319,18 @@ static int skl_get_module_info(struct skl_dev *skl,
break;
}
}
if (skl->nr_modules && ret)
return ret;
ret = -EIO;
list_for_each_entry(module, &skl->uuid_list, list) {
if (guid_equal(uuid_mod, &module->uuid)) {
mconfig->id.module_id = module->id;
mconfig->module->loadable = module->is_loadable;
ret = 0;
}
for (i = 0; i < MAX_IN_QUEUE; i++) {
pin_id = &mconfig->m_in_pin[i].id;
if (guid_equal(&pin_id->mod_uuid, &module->uuid))
......@@ -1351,7 +1344,7 @@ static int skl_get_module_info(struct skl_dev *skl,
}
}
return 0;
return ret;
}
static int skl_populate_modules(struct skl_dev *skl)
......
This diff is collapsed.
......@@ -81,6 +81,8 @@ enum skl_s_freq {
SKL_FS_INVALID
};
#define SKL_MAX_PARAMS_TYPES 4
enum skl_widget_type {
SKL_WIDGET_VMIXER = 1,
SKL_WIDGET_MIXER = 2,
......@@ -150,6 +152,21 @@ struct skl_up_down_mixer_cfg {
u32 ch_map;
} __packed;
struct skl_pin_format {
u32 pin_idx;
u32 buf_size;
struct skl_audio_data_format audio_fmt;
} __packed;
struct skl_base_cfg_ext {
u16 nr_input_pins;
u16 nr_output_pins;
u8 reserved[8];
u32 priv_param_length;
/* Input pin formats followed by output ones. */
struct skl_pin_format pins_fmt[0];
} __packed;
struct skl_algo_cfg {
struct skl_base_cfg base_cfg;
char params[];
......@@ -311,10 +328,8 @@ struct skl_pipe {
enum skl_module_state {
SKL_MODULE_UNINIT = 0,
SKL_MODULE_LOADED = 1,
SKL_MODULE_INIT_DONE = 2,
SKL_MODULE_BIND_DONE = 3,
SKL_MODULE_UNLOADED = 4,
SKL_MODULE_INIT_DONE = 1,
SKL_MODULE_BIND_DONE = 2,
};
enum d0i3_capability {
......@@ -373,6 +388,7 @@ struct skl_module_cfg {
struct skl_module *module;
int res_idx;
int fmt_idx;
int fmt_cfg_idx;
u8 domain;
bool homogenous_inputs;
bool homogenous_outputs;
......@@ -403,7 +419,7 @@ struct skl_module_cfg {
enum skl_hw_conn_type hw_conn_type;
enum skl_module_state m_state;
struct skl_pipe *pipe;
struct skl_specific_cfg formats_config;
struct skl_specific_cfg formats_config[SKL_MAX_PARAMS_TYPES];
struct skl_pipe_mcfg mod_cfg[SKL_MAX_MODULES_IN_PIPE];
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment