diff --git a/include/sound/sof/dai-intel.h b/include/sound/sof/dai-intel.h index 04e48227f542b5..1dae31aa53c66c 100644 --- a/include/sound/sof/dai-intel.h +++ b/include/sound/sof/dai-intel.h @@ -51,7 +51,8 @@ /* SSP Configuration Request - SOF_IPC_DAI_SSP_CONFIG */ struct sof_ipc_dai_ssp_params { - struct sof_ipc_hdr hdr; + uint32_t subdai_index; /* only used in multi-dai usages */ + uint32_t reserved0; uint16_t reserved1; uint16_t mclk_id; @@ -83,13 +84,15 @@ struct sof_ipc_dai_ssp_params { /* HDA Configuration Request - SOF_IPC_DAI_HDA_CONFIG */ struct sof_ipc_dai_hda_params { - struct sof_ipc_hdr hdr; + uint32_t subdai_index; /* only used in multi-dai usages */ + uint32_t reserved0; uint32_t link_dma_ch; } __packed; /* ALH Configuration Request - SOF_IPC_DAI_ALH_CONFIG */ struct sof_ipc_dai_alh_params { - struct sof_ipc_hdr hdr; + uint32_t subdai_index; /* only used in multi-dai usages */ + uint32_t reserved0; uint32_t stream_id; /* reserved for future use */ @@ -116,7 +119,7 @@ struct sof_ipc_dai_alh_params { * data integrity problems. */ struct sof_ipc_dai_dmic_pdm_ctrl { - struct sof_ipc_hdr hdr; + uint32_t reserved0[2]; uint16_t id; /**< PDM controller ID */ uint16_t enable_mic_a; /**< Use A (left) channel mic (0 or 1)*/ @@ -161,7 +164,8 @@ struct sof_ipc_dai_dmic_pdm_ctrl { * treated as an error. */ struct sof_ipc_dai_dmic_params { - struct sof_ipc_hdr hdr; + uint32_t subdai_index; /* only used in multi-dai usages */ + uint32_t reserved0; uint32_t driver_ipc_version; /**< Version (1..N) */ uint32_t pdmclk_min; /**< Minimum microphone clock in Hz (100000..N) */ diff --git a/include/sound/sof/dai.h b/include/sound/sof/dai.h index 2565edd336f15d..c66bb9ea1257a7 100644 --- a/include/sound/sof/dai.h +++ b/include/sound/sof/dai.h @@ -9,6 +9,7 @@ #ifndef __INCLUDE_SOUND_SOF_DAI_H__ #define __INCLUDE_SOUND_SOF_DAI_H__ +#include #include #include #include @@ -50,23 +51,31 @@ enum sof_ipc_dai_type { SOF_DAI_INTEL_SSP, /**< Intel SSP */ SOF_DAI_INTEL_DMIC, /**< Intel DMIC */ SOF_DAI_INTEL_HDA, /**< Intel HD/A */ - SOF_DAI_INTEL_ALH, /**< Intel ALH */ - SOF_DAI_IMX_SAI, /**< i.MX SAI */ - SOF_DAI_IMX_ESAI, /**< i.MX ESAI */ + SOF_DAI_INTEL_ALH, /**< Intel ALH */ + SOF_DAI_IMX_SAI, /**< i.MX SAI */ + SOF_DAI_IMX_ESAI, /**< i.MX ESAI */ + SOF_DAI_MULTIDAI = 0xFFFF /**< config with multiple elements of the same dai type */ }; /* general purpose DAI configuration */ struct sof_ipc_dai_config { struct sof_ipc_cmd_hdr hdr; - uint32_t type; /**< DAI type - enum sof_ipc_dai_type */ + + uint16_t type; /**< DAI type - enum sof_ipc_dai_type */ + uint16_t subdai_type; /**< only used in multi-dai cases */ uint32_t dai_index; /**< index of this type dai */ /* physical protocol and clocking */ uint16_t format; /**< SOF_DAI_FMT_ */ - uint16_t reserved16; /**< alignment */ + + /* we can either have multiple sub-DAIs or multiple configs, not both */ + uint16_t num_payloads; /**< number of configs or number of sub-DAIs */ + + uint16_t config_index; /**< index in dai_data */ /* reserved for future use */ - uint32_t reserved[8]; + uint32_t reserved16; + uint32_t reserved[7]; /* HW specific data */ union { @@ -76,7 +85,13 @@ struct sof_ipc_dai_config { struct sof_ipc_dai_alh_params alh; struct sof_ipc_dai_esai_params esai; struct sof_ipc_dai_sai_params sai; - }; + } dai_data[0]; + + /* + * multi-dai stream maps. The ext_id used needs to match subdai_index + * in each _params structure above + */ + struct sof_ipc_stream_map stream_map; } __packed; #endif diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c index 9c6e3f990ee31d..6f9f05da7ddf70 100644 --- a/sound/soc/sof/intel/hda-dai.c +++ b/sound/soc/sof/intel/hda-dai.c @@ -176,7 +176,7 @@ static int hda_link_config_ipc(struct sof_intel_hda_stream *hda_stream, } /* update config with stream tag */ - config->hda.link_dma_ch = channel; + config->dai_data[0].hda.link_dma_ch = channel; /* send IPC */ ret = sof_ipc_tx_message(hda_stream->sdev->ipc, diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index f225152c21d78d..d75fd92b4ecf18 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -67,7 +67,7 @@ static int sdw_params_stream(struct device *dev, config.hdr.cmd = SOF_IPC_GLB_DAI_MSG | SOF_IPC_DAI_CONFIG; config.type = SOF_DAI_INTEL_ALH; config.dai_index = (link_id << 8) | (d->id); - config.alh.stream_id = alh_stream_id; + config.dai_data[0].alh.stream_id = alh_stream_id; /* send message to DSP */ ret = sof_ipc_tx_message(sdev->ipc, @@ -98,7 +98,7 @@ static int sdw_free_stream(struct device *dev, config.hdr.cmd = SOF_IPC_GLB_DAI_MSG | SOF_IPC_DAI_CONFIG; config.type = SOF_DAI_INTEL_ALH; config.dai_index = (link_id << 8) | d->id; - config.alh.stream_id = 0xFFFF; /* invalid value on purpose */ + config.dai_data[0].alh.stream_id = 0xFFFF; /* invalid value on purpose */ /* send message to DSP */ ret = sof_ipc_tx_message(sdev->ipc, diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c index c3b1d2f7672f07..8041e08d909dd0 100644 --- a/sound/soc/sof/pcm.c +++ b/sound/soc/sof/pcm.c @@ -679,10 +679,10 @@ static int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, /* read rate and channels from topology */ switch (dai->dai_config->type) { case SOF_DAI_INTEL_SSP: - rate->min = dai->dai_config->ssp.fsync_rate; - rate->max = dai->dai_config->ssp.fsync_rate; - channels->min = dai->dai_config->ssp.tdm_slots; - channels->max = dai->dai_config->ssp.tdm_slots; + rate->min = dai->dai_config->dai_data[0].ssp.fsync_rate; + rate->max = dai->dai_config->dai_data[0].ssp.fsync_rate; + channels->min = dai->dai_config->dai_data[0].ssp.tdm_slots; + channels->max = dai->dai_config->dai_data[0].ssp.tdm_slots; dev_dbg(component->dev, "rate_min: %d rate_max: %d\n", rate->min, rate->max); @@ -707,16 +707,16 @@ static int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, /* do nothing for ALH dai_link */ break; case SOF_DAI_IMX_ESAI: - channels->min = dai->dai_config->esai.tdm_slots; - channels->max = dai->dai_config->esai.tdm_slots; + channels->min = dai->dai_config->dai_data[0].esai.tdm_slots; + channels->max = dai->dai_config->dai_data[0].esai.tdm_slots; dev_dbg(component->dev, "channels_min: %d channels_max: %d\n", channels->min, channels->max); break; case SOF_DAI_IMX_SAI: - channels->min = dai->dai_config->sai.tdm_slots; - channels->max = dai->dai_config->sai.tdm_slots; + channels->min = dai->dai_config->dai_data[0].sai.tdm_slots; + channels->max = dai->dai_config->dai_data[0].sai.tdm_slots; dev_dbg(component->dev, "channels_min: %d channels_max: %d\n", diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c index 75f2ef2bd94be0..7cb33352de24c8 100644 --- a/sound/soc/sof/sof-audio.c +++ b/sound/soc/sof/sof-audio.c @@ -244,7 +244,7 @@ int sof_restore_pipelines(struct device *dev) * the dai config in the DSP. */ if (config->type == SOF_DAI_INTEL_HDA) - config->hda.link_dma_ch = DMA_CHAN_INVALID; + config->dai_data[0].hda.link_dma_ch = DMA_CHAN_INVALID; ret = sof_ipc_tx_message(sdev->ipc, config->hdr.cmd, config, diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index 9f4f8868b3860b..10984af926f860 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -2644,10 +2644,11 @@ static int sof_link_ssp_load(struct snd_soc_component *scomp, int index, sof_dai_set_format(hw_config, config); /* init IPC */ - memset(&config->ssp, 0, sizeof(struct sof_ipc_dai_ssp_params)); + memset(&config->dai_data[0].ssp, 0, + sizeof(struct sof_ipc_dai_ssp_params)); config->hdr.size = size; - ret = sof_parse_tokens(scomp, &config->ssp, ssp_tokens, + ret = sof_parse_tokens(scomp, &config->dai_data[0].ssp, ssp_tokens, ARRAY_SIZE(ssp_tokens), private->array, le32_to_cpu(private->size)); if (ret != 0) { @@ -2656,30 +2657,37 @@ static int sof_link_ssp_load(struct snd_soc_component *scomp, int index, return ret; } - config->ssp.mclk_rate = le32_to_cpu(hw_config->mclk_rate); - config->ssp.bclk_rate = le32_to_cpu(hw_config->bclk_rate); - config->ssp.fsync_rate = le32_to_cpu(hw_config->fsync_rate); - config->ssp.tdm_slots = le32_to_cpu(hw_config->tdm_slots); - config->ssp.tdm_slot_width = le32_to_cpu(hw_config->tdm_slot_width); - config->ssp.mclk_direction = hw_config->mclk_direction; - config->ssp.rx_slots = le32_to_cpu(hw_config->rx_slots); - config->ssp.tx_slots = le32_to_cpu(hw_config->tx_slots); + config->dai_data[0].ssp.mclk_rate = le32_to_cpu(hw_config->mclk_rate); + config->dai_data[0].ssp.bclk_rate = le32_to_cpu(hw_config->bclk_rate); + config->dai_data[0].ssp.fsync_rate = le32_to_cpu(hw_config->fsync_rate); + config->dai_data[0].ssp.tdm_slots = le32_to_cpu(hw_config->tdm_slots); + config->dai_data[0].ssp.tdm_slot_width = + le32_to_cpu(hw_config->tdm_slot_width); + config->dai_data[0].ssp.mclk_direction = hw_config->mclk_direction; + config->dai_data[0].ssp.rx_slots = le32_to_cpu(hw_config->rx_slots); + config->dai_data[0].ssp.tx_slots = le32_to_cpu(hw_config->tx_slots); dev_dbg(scomp->dev, "tplg: config SSP%d fmt 0x%x mclk %d bclk %d fclk %d width (%d)%d slots %d mclk id %d quirks %d\n", config->dai_index, config->format, - config->ssp.mclk_rate, config->ssp.bclk_rate, - config->ssp.fsync_rate, config->ssp.sample_valid_bits, - config->ssp.tdm_slot_width, config->ssp.tdm_slots, - config->ssp.mclk_id, config->ssp.quirks); + config->dai_data[0].ssp.mclk_rate, + config->dai_data[0].ssp.bclk_rate, + config->dai_data[0].ssp.fsync_rate, + config->dai_data[0].ssp.sample_valid_bits, + config->dai_data[0].ssp.tdm_slot_width, + config->dai_data[0].ssp.tdm_slots, + config->dai_data[0].ssp.mclk_id, + config->dai_data[0].ssp.quirks); /* validate SSP fsync rate and channel count */ - if (config->ssp.fsync_rate < 8000 || config->ssp.fsync_rate > 192000) { + if (config->dai_data[0].ssp.fsync_rate < 8000 || + config->dai_data[0].ssp.fsync_rate > 192000) { dev_err(scomp->dev, "error: invalid fsync rate for SSP%d\n", config->dai_index); return -EINVAL; } - if (config->ssp.tdm_slots < 1 || config->ssp.tdm_slots > 8) { + if (config->dai_data[0].ssp.tdm_slots < 1 || + config->dai_data[0].ssp.tdm_slots > 8) { dev_err(scomp->dev, "error: invalid channel count for SSP%d\n", config->dai_index); return -EINVAL; @@ -2721,10 +2729,11 @@ static int sof_link_sai_load(struct snd_soc_component *scomp, int index, sof_dai_set_format(hw_config, config); /* init IPC */ - memset(&config->sai, 0, sizeof(struct sof_ipc_dai_sai_params)); + memset(&config->dai_data[0].sai, 0, + sizeof(struct sof_ipc_dai_sai_params)); config->hdr.size = size; - ret = sof_parse_tokens(scomp, &config->sai, sai_tokens, + ret = sof_parse_tokens(scomp, &config->dai_data[0].sai, sai_tokens, ARRAY_SIZE(sai_tokens), private->array, le32_to_cpu(private->size)); if (ret != 0) { @@ -2733,21 +2742,25 @@ static int sof_link_sai_load(struct snd_soc_component *scomp, int index, return ret; } - config->sai.mclk_rate = le32_to_cpu(hw_config->mclk_rate); - config->sai.mclk_direction = hw_config->mclk_direction; + config->dai_data[0].sai.mclk_rate = le32_to_cpu(hw_config->mclk_rate); + config->dai_data[0].sai.mclk_direction = hw_config->mclk_direction; - config->sai.tdm_slots = le32_to_cpu(hw_config->tdm_slots); - config->sai.tdm_slot_width = le32_to_cpu(hw_config->tdm_slot_width); - config->sai.rx_slots = le32_to_cpu(hw_config->rx_slots); - config->sai.tx_slots = le32_to_cpu(hw_config->tx_slots); + config->dai_data[0].sai.tdm_slots = le32_to_cpu(hw_config->tdm_slots); + config->dai_data[0].sai.tdm_slot_width = + le32_to_cpu(hw_config->tdm_slot_width); + config->dai_data[0].sai.rx_slots = le32_to_cpu(hw_config->rx_slots); + config->dai_data[0].sai.tx_slots = le32_to_cpu(hw_config->tx_slots); dev_info(scomp->dev, "tplg: config SAI%d fmt 0x%x mclk %d width %d slots %d mclk id %d\n", - config->dai_index, config->format, - config->sai.mclk_rate, config->sai.tdm_slot_width, - config->sai.tdm_slots, config->sai.mclk_id); - - if (config->sai.tdm_slots < 1 || config->sai.tdm_slots > 8) { + config->dai_index, config->format, + config->dai_data[0].sai.mclk_rate, + config->dai_data[0].sai.tdm_slot_width, + config->dai_data[0].sai.tdm_slots, + config->dai_data[0].sai.mclk_id); + + if (config->dai_data[0].sai.tdm_slots < 1 || + config->dai_data[0].sai.tdm_slots > 8) { dev_err(scomp->dev, "error: invalid channel count for SAI%d\n", config->dai_index); return -EINVAL; @@ -2789,10 +2802,11 @@ static int sof_link_esai_load(struct snd_soc_component *scomp, int index, sof_dai_set_format(hw_config, config); /* init IPC */ - memset(&config->esai, 0, sizeof(struct sof_ipc_dai_esai_params)); + memset(&config->dai_data[0].esai, 0, + sizeof(struct sof_ipc_dai_esai_params)); config->hdr.size = size; - ret = sof_parse_tokens(scomp, &config->esai, esai_tokens, + ret = sof_parse_tokens(scomp, &config->dai_data[0].esai, esai_tokens, ARRAY_SIZE(esai_tokens), private->array, le32_to_cpu(private->size)); if (ret != 0) { @@ -2801,22 +2815,27 @@ static int sof_link_esai_load(struct snd_soc_component *scomp, int index, return ret; } - config->esai.mclk_rate = le32_to_cpu(hw_config->mclk_rate); - config->esai.bclk_rate = le32_to_cpu(hw_config->bclk_rate); - config->esai.fsync_rate = le32_to_cpu(hw_config->fsync_rate); - config->esai.mclk_direction = hw_config->mclk_direction; - config->esai.tdm_slots = le32_to_cpu(hw_config->tdm_slots); - config->esai.tdm_slot_width = le32_to_cpu(hw_config->tdm_slot_width); - config->esai.rx_slots = le32_to_cpu(hw_config->rx_slots); - config->esai.tx_slots = le32_to_cpu(hw_config->tx_slots); + config->dai_data[0].esai.mclk_rate = le32_to_cpu(hw_config->mclk_rate); + config->dai_data[0].esai.bclk_rate = le32_to_cpu(hw_config->bclk_rate); + config->dai_data[0].esai.fsync_rate = + le32_to_cpu(hw_config->fsync_rate); + config->dai_data[0].esai.mclk_direction = hw_config->mclk_direction; + config->dai_data[0].esai.tdm_slots = le32_to_cpu(hw_config->tdm_slots); + config->dai_data[0].esai.tdm_slot_width = + le32_to_cpu(hw_config->tdm_slot_width); + config->dai_data[0].esai.rx_slots = le32_to_cpu(hw_config->rx_slots); + config->dai_data[0].esai.tx_slots = le32_to_cpu(hw_config->tx_slots); dev_info(scomp->dev, "tplg: config ESAI%d fmt 0x%x mclk %d width %d slots %d mclk id %d\n", - config->dai_index, config->format, - config->esai.mclk_rate, config->esai.tdm_slot_width, - config->esai.tdm_slots, config->esai.mclk_id); - - if (config->esai.tdm_slots < 1 || config->esai.tdm_slots > 8) { + config->dai_index, config->format, + config->dai_data[0].esai.mclk_rate, + config->dai_data[0].esai.tdm_slot_width, + config->dai_data[0].esai.tdm_slots, + config->dai_data[0].esai.mclk_id); + + if (config->dai_data[0].esai.tdm_slots < 1 || + config->dai_data[0].esai.tdm_slots > 8) { dev_err(scomp->dev, "error: invalid channel count for ESAI%d\n", config->dai_index); return -EINVAL; @@ -2861,10 +2880,11 @@ static int sof_link_dmic_load(struct snd_soc_component *scomp, int index, * that does not include the PDM controller config array * Set the common params to 0. */ - memset(&config->dmic, 0, sizeof(struct sof_ipc_dai_dmic_params)); + memset(&config->dai_data[0].dmic, 0, + sizeof(struct sof_ipc_dai_dmic_params)); /* get DMIC tokens */ - ret = sof_parse_tokens(scomp, &config->dmic, dmic_tokens, + ret = sof_parse_tokens(scomp, &config->dai_data[0].dmic, dmic_tokens, ARRAY_SIZE(dmic_tokens), private->array, le32_to_cpu(private->size)); if (ret != 0) { @@ -2879,7 +2899,7 @@ static int sof_link_dmic_load(struct snd_soc_component *scomp, int index, * This will be the ipc payload for setting dai config */ size = sizeof(*config) + sizeof(struct sof_ipc_dai_dmic_pdm_ctrl) * - config->dmic.num_pdm_active; + config->dai_data[0].dmic.num_pdm_active; ipc_config = kzalloc(size, GFP_KERNEL); if (!ipc_config) @@ -2899,7 +2919,8 @@ static int sof_link_dmic_load(struct snd_soc_component *scomp, int index, } /* get DMIC PDM tokens */ - ret = sof_parse_tokens(scomp, &ipc_config->dmic.pdm[0], dmic_pdm_tokens, + ret = sof_parse_tokens(scomp, &ipc_config->dai_data[0].dmic.pdm[0], + dmic_pdm_tokens, ARRAY_SIZE(dmic_pdm_tokens), private->array, le32_to_cpu(private->size)); if (ret != 0) { @@ -2913,34 +2934,38 @@ static int sof_link_dmic_load(struct snd_soc_component *scomp, int index, /* debug messages */ dev_dbg(scomp->dev, "tplg: config DMIC%d driver version %d\n", - ipc_config->dai_index, ipc_config->dmic.driver_ipc_version); + ipc_config->dai_index, + ipc_config->dai_data[0].dmic.driver_ipc_version); dev_dbg(scomp->dev, "pdmclk_min %d pdm_clkmax %d duty_min %hd\n", - ipc_config->dmic.pdmclk_min, ipc_config->dmic.pdmclk_max, - ipc_config->dmic.duty_min); + ipc_config->dai_data[0].dmic.pdmclk_min, + ipc_config->dai_data[0].dmic.pdmclk_max, + ipc_config->dai_data[0].dmic.duty_min); dev_dbg(scomp->dev, "duty_max %hd fifo_fs %d num_pdms active %d\n", - ipc_config->dmic.duty_max, ipc_config->dmic.fifo_fs, - ipc_config->dmic.num_pdm_active); + ipc_config->dai_data[0].dmic.duty_max, + ipc_config->dai_data[0].dmic.fifo_fs, + ipc_config->dai_data[0].dmic.num_pdm_active); dev_dbg(scomp->dev, "fifo word length %hd\n", - ipc_config->dmic.fifo_bits); + ipc_config->dai_data[0].dmic.fifo_bits); - for (j = 0; j < ipc_config->dmic.num_pdm_active; j++) { + for (j = 0; j < ipc_config->dai_data[0].dmic.num_pdm_active; j++) { dev_dbg(scomp->dev, "pdm %hd mic a %hd mic b %hd\n", - ipc_config->dmic.pdm[j].id, - ipc_config->dmic.pdm[j].enable_mic_a, - ipc_config->dmic.pdm[j].enable_mic_b); + ipc_config->dai_data[0].dmic.pdm[j].id, + ipc_config->dai_data[0].dmic.pdm[j].enable_mic_a, + ipc_config->dai_data[0].dmic.pdm[j].enable_mic_b); dev_dbg(scomp->dev, "pdm %hd polarity a %hd polarity b %hd\n", - ipc_config->dmic.pdm[j].id, - ipc_config->dmic.pdm[j].polarity_mic_a, - ipc_config->dmic.pdm[j].polarity_mic_b); + ipc_config->dai_data[0].dmic.pdm[j].id, + ipc_config->dai_data[0].dmic.pdm[j].polarity_mic_a, + ipc_config->dai_data[0].dmic.pdm[j].polarity_mic_b); dev_dbg(scomp->dev, "pdm %hd clk_edge %hd skew %hd\n", - ipc_config->dmic.pdm[j].id, - ipc_config->dmic.pdm[j].clk_edge, - ipc_config->dmic.pdm[j].skew); + ipc_config->dai_data[0].dmic.pdm[j].id, + ipc_config->dai_data[0].dmic.pdm[j].clk_edge, + ipc_config->dai_data[0].dmic.pdm[j].skew); } if (SOF_ABI_VER(v->major, v->minor, v->micro) < SOF_ABI_VER(3, 0, 1)) { /* this takes care of backwards compatible handling of fifo_bits_b */ - ipc_config->dmic.reserved_2 = ipc_config->dmic.fifo_bits; + ipc_config->dai_data[0].dmic.reserved_2 = + ipc_config->dai_data[0].dmic.fifo_bits; } /* send message to DSP */ @@ -2991,7 +3016,7 @@ static int sof_link_hda_process(struct snd_sof_dev *sdev, config->dai_index = sof_dai->comp_dai.dai_index; found = 1; - config->hda.link_dma_ch = DMA_CHAN_INVALID; + config->dai_data[0].hda.link_dma_ch = DMA_CHAN_INVALID; /* save config in dai component */ sof_dai->dai_config = kmemdup(config, size, GFP_KERNEL); @@ -3041,7 +3066,8 @@ static int sof_link_hda_load(struct snd_soc_component *scomp, int index, int ret; /* init IPC */ - memset(&config->hda, 0, sizeof(struct sof_ipc_dai_hda_params)); + memset(&config->dai_data[0].hda, 0, + sizeof(struct sof_ipc_dai_hda_params)); config->hdr.size = size; /* get any bespoke DAI tokens */