From 735ad886a5e63756f5b61238d33cad4c437a2cd8 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 10 Feb 2020 16:46:05 -0600 Subject: [PATCH 1/2] ipc: dai: remove unused hdr field in params We don't use this field, move back to reserved. Signed-off-by: Pierre-Louis Bossart --- src/include/ipc/dai-imx.h | 4 ++-- src/include/ipc/dai-intel.h | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/include/ipc/dai-imx.h b/src/include/ipc/dai-imx.h index 90c4ecc96ccd..59ec4b400efa 100644 --- a/src/include/ipc/dai-imx.h +++ b/src/include/ipc/dai-imx.h @@ -13,7 +13,7 @@ /* ESAI Configuration Request - SOF_IPC_DAI_ESAI_CONFIG */ struct sof_ipc_dai_esai_params { - struct sof_ipc_hdr hdr; + uint32_t reserved0[2]; /* MCLK */ uint16_t reserved1; @@ -32,7 +32,7 @@ struct sof_ipc_dai_esai_params { /* SAI Configuration Request - SOF_IPC_DAI_SAI_CONFIG */ struct sof_ipc_dai_sai_params { - struct sof_ipc_hdr hdr; + uint32_t reserved0[2]; /* MCLK */ uint16_t reserved1; diff --git a/src/include/ipc/dai-intel.h b/src/include/ipc/dai-intel.h index e926e7b7a619..fc0da0c745d0 100644 --- a/src/include/ipc/dai-intel.h +++ b/src/include/ipc/dai-intel.h @@ -59,7 +59,7 @@ /* SSP Configuration Request - SOF_IPC_DAI_SSP_CONFIG */ struct sof_ipc_dai_ssp_params { - struct sof_ipc_hdr hdr; + uint32_t reserved0[2]; uint16_t reserved1; uint16_t mclk_id; @@ -91,13 +91,13 @@ 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 reserved0[2]; uint32_t link_dma_ch; } __attribute__((packed)); /* ALH Configuration Request - SOF_IPC_DAI_ALH_CONFIG */ struct sof_ipc_dai_alh_params { - struct sof_ipc_hdr hdr; + uint32_t reserved0[2]; uint32_t stream_id; /* reserved for future use */ @@ -124,7 +124,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)*/ @@ -169,7 +169,7 @@ struct sof_ipc_dai_dmic_pdm_ctrl { * treated as an error. */ struct sof_ipc_dai_dmic_params { - struct sof_ipc_hdr hdr; + uint32_t reserved0[2]; uint32_t driver_ipc_version; /**< Version (1..N) */ uint32_t pdmclk_min; /**< Minimum microphone clock in Hz (100000..N) */ From c360ffa7d48a2eee5515e2ffa8d74eab0b0c647c Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 10 Feb 2020 17:10:30 -0600 Subject: [PATCH 2/2] dai: add multi-dai configuration The multi-dai configuration is only a bundle of elementary DAIs, combined with a stream map to generate the right data for each elementary DAI. When the multi-dai configuration is used, a DAI subtype such as ALH needs to be used, and the payload for each elementary DAIs is associated with a specific subdai_index. For example, with the MULTI_DAI type, subtype ALH, num_payloads 2, the first alh_params would use a subdai_index 0x102 while the second would use 0x202. The stream map ext_id values would be restricted to those two subdai_index. When the multi-dai configuration is not used, the dai_config can be used to provide multiple configurations to an elementary dai. To simplify data handling all configurations are passed in a single IPC, and the firmware only needs to use the config_index field to use the relevant configuration. In this pathset the dai_data is always accessed with a zero index, but in the future the driver may signal a different configuration is required for a specific use case. Update DAI-specific files as needed to avoid breaking compilation and bisect. Signed-off-by: Pierre-Louis Bossart --- src/audio/dai.c | 12 ++--- src/drivers/intel/baytrail/ssp.c | 64 ++++++++++++++--------- src/drivers/intel/cavs/dmic.c | 22 ++++---- src/drivers/intel/cavs/ssp.c | 87 ++++++++++++++++++-------------- src/include/ipc/dai-imx.h | 6 ++- src/include/ipc/dai-intel.h | 12 +++-- src/include/ipc/dai.h | 23 +++++++-- 7 files changed, 138 insertions(+), 88 deletions(-) diff --git a/src/audio/dai.c b/src/audio/dai.c index 35def51f7956..704af97c1c33 100644 --- a/src/audio/dai.c +++ b/src/audio/dai.c @@ -688,7 +688,7 @@ static int dai_config(struct comp_dev *dev, struct sof_ipc_dai_config *config) switch (config->type) { case SOF_DAI_INTEL_SSP: /* set dma burst elems to slot number */ - dd->config.burst_elems = config->ssp.tdm_slots; + dd->config.burst_elems = config->dai_data[0].ssp.tdm_slots; break; case SOF_DAI_INTEL_DMIC: tracev_dai_comp_with_ids(dev, "dai_config(), config->type = SOF_DAI_INTEL_DMIC"); @@ -697,11 +697,11 @@ static int dai_config(struct comp_dev *dev, struct sof_ipc_dai_config *config) dd->config.burst_elems = 8; trace_dai_comp_with_ids(dev, "dai_config(), config->dmic.fifo_bits = %u config->dmic.num_pdm_active = %u", - config->dmic.fifo_bits, - config->dmic.num_pdm_active); + config->dai_data[0].dmic.fifo_bits, + config->dai_data[0].dmic.num_pdm_active); break; case SOF_DAI_INTEL_HDA: - channel = config->hda.link_dma_ch; + channel = config->dai_data[0].hda.link_dma_ch; trace_dai_comp_with_ids(dev, "dai_config(), channel = %d", channel); @@ -729,8 +729,8 @@ static int dai_config(struct comp_dev *dev, struct sof_ipc_dai_config *config) /* As with HDA, the DMA channel is assigned in runtime, * not during topology parsing. */ - channel = config->alh.stream_id; - dd->stream_id = config->alh.stream_id; + channel = config->dai_data[0].alh.stream_id; + dd->stream_id = config->dai_data[0].alh.stream_id; trace_dai_comp_with_ids(dev, "dai_config(), channel = %d", channel); break; diff --git a/src/drivers/intel/baytrail/ssp.c b/src/drivers/intel/baytrail/ssp.c index 72498e02c69f..e79321f57edc 100644 --- a/src/drivers/intel/baytrail/ssp.c +++ b/src/drivers/intel/baytrail/ssp.c @@ -165,7 +165,7 @@ static int ssp_set_config(struct dai *dai, sspsp = SSPSP_ETDS; /* last value (bit 0) */ ssp->config = *config; - ssp->params = config->ssp; + ssp->params = config->dai_data[0].ssp; /* clock masters */ /* @@ -281,7 +281,8 @@ static int ssp_set_config(struct dai *dai, } /* BCLK is generated from MCLK - must be divisable */ - if (config->ssp.mclk_rate % config->ssp.bclk_rate) { + if (config->dai_data[0].ssp.mclk_rate % + config->dai_data[0].ssp.bclk_rate) { trace_ssp_error("ssp_set_config() error: " "MCLK is not divisable"); ret = -EINVAL; @@ -289,7 +290,8 @@ static int ssp_set_config(struct dai *dai, } /* divisor must be within SCR range */ - mdiv = (config->ssp.mclk_rate / config->ssp.bclk_rate) - 1; + mdiv = (config->dai_data[0].ssp.mclk_rate / + config->dai_data[0].ssp.bclk_rate) - 1; if (mdiv > (SSCR0_SCR_MASK >> 8)) { trace_ssp_error("ssp_set_config() error: " "divisor is not within SCR range"); @@ -301,7 +303,8 @@ static int ssp_set_config(struct dai *dai, sscr0 |= SSCR0_SCR(mdiv); /* calc frame width based on BCLK and rate - must be divisable */ - if (config->ssp.bclk_rate % config->ssp.fsync_rate) { + if (config->dai_data[0].ssp.bclk_rate % + config->dai_data[0].ssp.fsync_rate) { trace_ssp_error("ssp_set_config() error: " "BLCK is not divisable"); ret = -EINVAL; @@ -309,16 +312,17 @@ static int ssp_set_config(struct dai *dai, } /* must be enouch BCLKs for data */ - bdiv = config->ssp.bclk_rate / config->ssp.fsync_rate; - if (bdiv < config->ssp.tdm_slot_width * - config->ssp.tdm_slots) { + bdiv = config->dai_data[0].ssp.bclk_rate / + config->dai_data[0].ssp.fsync_rate; + if (bdiv < config->dai_data[0].ssp.tdm_slot_width * + config->dai_data[0].ssp.tdm_slots) { trace_ssp_error("ssp_set_config() error: not enough BCLKs"); ret = -EINVAL; goto out; } /* tdm_slot_width must be <= 38 for SSP */ - if (config->ssp.tdm_slot_width > 38) { + if (config->dai_data[0].ssp.tdm_slot_width > 38) { trace_ssp_error("ssp_set_config() error: tdm_slot_width > 38"); ret = -EINVAL; goto out; @@ -334,7 +338,7 @@ static int ssp_set_config(struct dai *dai, sscr3 |= SSCR3_I2S_MODE_EN | SSCR3_I2S_TX_EN | SSCR3_I2S_RX_EN; /* set asserted frame length */ - frame_len = config->ssp.tdm_slot_width; + frame_len = config->dai_data[0].ssp.tdm_slot_width; /* handle frame polarity, I2S default is falling/active low */ sspsp |= SSPSP_SFRMP(!inverted_frame); @@ -364,7 +368,7 @@ static int ssp_set_config(struct dai *dai, sscr3 |= SSCR3_I2S_MODE_EN | SSCR3_I2S_TX_EN | SSCR3_I2S_RX_EN; /* set asserted frame length */ - frame_len = config->ssp.tdm_slot_width; + frame_len = config->dai_data[0].ssp.tdm_slot_width; /* LEFT_J default is rising/active high, opposite of I2S */ sspsp |= SSPSP_SFRMP(inverted_frame); @@ -389,7 +393,8 @@ static int ssp_set_config(struct dai *dai, start_delay = 1; - sscr0 |= SSCR0_MOD | SSCR0_FRDC(config->ssp.tdm_slots); + sscr0 |= SSCR0_MOD | + SSCR0_FRDC(config->dai_data[0].ssp.tdm_slots); /* set asserted frame length */ frame_len = 1; @@ -405,19 +410,24 @@ static int ssp_set_config(struct dai *dai, * total frame period (both asserted and * deasserted time of frame) */ - if (cbs) - sscr4 |= SSCR4_TOT_FRM_PRD(config->ssp.tdm_slots * - config->ssp.tdm_slot_width); + if (cbs) { + int tdm_slots = config->dai_data[0].ssp.tdm_slots; + int tdm_slot_width = + config->dai_data[0].ssp.tdm_slot_width; + + sscr4 |= SSCR4_TOT_FRM_PRD(tdm_slots * tdm_slot_width); + } - active_tx_slots = popcount(config->ssp.tx_slots); - active_rx_slots = popcount(config->ssp.rx_slots); + active_tx_slots = popcount(config->dai_data[0].ssp.tx_slots); + active_rx_slots = popcount(config->dai_data[0].ssp.rx_slots); break; case SOF_DAI_FMT_DSP_B: start_delay = 0; - sscr0 |= SSCR0_MOD | SSCR0_FRDC(config->ssp.tdm_slots); + sscr0 |= SSCR0_MOD | + SSCR0_FRDC(config->dai_data[0].ssp.tdm_slots); /* set asserted frame length */ frame_len = 1; @@ -433,12 +443,16 @@ static int ssp_set_config(struct dai *dai, * total frame period (both asserted and * deasserted time of frame */ - if (cbs) - sscr4 |= SSCR4_TOT_FRM_PRD(config->ssp.tdm_slots * - config->ssp.tdm_slot_width); + if (cbs) { + int tdm_slots = config->dai_data[0].ssp.tdm_slots; + int tdm_slot_width = + config->dai_data[0].ssp.tdm_slot_width; + + sscr4 |= SSCR4_TOT_FRM_PRD(tdm_slots * tdm_slot_width); + } - active_tx_slots = popcount(config->ssp.tx_slots); - active_rx_slots = popcount(config->ssp.rx_slots); + active_tx_slots = popcount(config->dai_data[0].ssp.tx_slots); + active_rx_slots = popcount(config->dai_data[0].ssp.rx_slots); break; default: @@ -452,7 +466,7 @@ static int ssp_set_config(struct dai *dai, sspsp |= SSPSP_SFRMWDTH(frame_len); sscr5 |= SSCR5_FRM_ASRT_CLOCKS(frame_len); - data_size = config->ssp.sample_valid_bits; + data_size = config->dai_data[0].ssp.sample_valid_bits; if (data_size > 16) sscr0 |= (SSCR0_EDSS | SSCR0_DSIZE(data_size - 16)); @@ -473,8 +487,8 @@ static int ssp_set_config(struct dai *dai, ssp_write(dai, SSCR5, sscr5); ssp_write(dai, SSPSP, sspsp); ssp_write(dai, SFIFOTT, sfifott); - ssp_write(dai, SSTSA, config->ssp.tx_slots); - ssp_write(dai, SSRSA, config->ssp.rx_slots); + ssp_write(dai, SSTSA, config->dai_data[0].ssp.tx_slots); + ssp_write(dai, SSRSA, config->dai_data[0].ssp.rx_slots); ssp->state[DAI_DIR_PLAYBACK] = COMP_STATE_PREPARE; ssp->state[DAI_DIR_CAPTURE] = COMP_STATE_PREPARE; diff --git a/src/drivers/intel/cavs/dmic.c b/src/drivers/intel/cavs/dmic.c index a3a9c3557894..f29f9c577e4f 100644 --- a/src/drivers/intel/cavs/dmic.c +++ b/src/drivers/intel/cavs/dmic.c @@ -1077,7 +1077,7 @@ static int dmic_set_config(struct dai *dai, struct sof_ipc_dai_config *config) trace_dmic_id(dai, "dmic_set_config()"); - if (config->dmic.driver_ipc_version != DMIC_IPC_VERSION) { + if (config->dai_data[0].dmic.driver_ipc_version != DMIC_IPC_VERSION) { trace_error_dmic_id(dai, "dmic_set_config() error: wrong ipc version"); return -EINVAL; } @@ -1085,8 +1085,8 @@ static int dmic_set_config(struct dai *dai, struct sof_ipc_dai_config *config) /* Compute unmute ramp gain update coefficient. Use the value from * topology if it is non-zero, otherwise use default length. */ - if (config->dmic.unmute_ramp_time) - unmute_ramp_time_ms = config->dmic.unmute_ramp_time; + if (config->dai_data[0].dmic.unmute_ramp_time) + unmute_ramp_time_ms = config->dai_data[0].dmic.unmute_ramp_time; else unmute_ramp_time_ms = LOGRAMP_TIME_MS; @@ -1102,7 +1102,7 @@ static int dmic_set_config(struct dai *dai, struct sof_ipc_dai_config *config) return -EINVAL; } - if (config->dmic.num_pdm_active > DMIC_HW_CONTROLLERS) { + if (config->dai_data[0].dmic.num_pdm_active > DMIC_HW_CONTROLLERS) { trace_error_dmic_id(dai, "dmic_set_config() error: the requested PDM controllers count exceeds platform capability"); return -EINVAL; } @@ -1136,19 +1136,21 @@ static int dmic_set_config(struct dai *dai, struct sof_ipc_dai_config *config) /* Copy the new DMIC params to persistent. The last request * determines the parameters. */ - ret = memcpy_s(dmic_prm[di], sizeof(*dmic_prm[di]), &config->dmic, + ret = memcpy_s(dmic_prm[di], sizeof(*dmic_prm[di]), + &config->dai_data[0].dmic, sizeof(struct sof_ipc_dai_dmic_params)); assert(!ret); /* copy the pdm controller params from ipc */ for (i = 0; i < DMIC_HW_CONTROLLERS; i++) { dmic_prm[di]->pdm[i].id = i; - for (j = 0; j < config->dmic.num_pdm_active; j++) { + for (j = 0; j < config->dai_data[0].dmic.num_pdm_active; j++) { /* copy the pdm controller params id the id's match */ - if (dmic_prm[di]->pdm[i].id == config->dmic.pdm[j].id) { + if (dmic_prm[di]->pdm[i].id == + config->dai_data[0].dmic.pdm[j].id) { ret = memcpy_s(&dmic_prm[di]->pdm[i], sizeof(dmic_prm[di]->pdm[i]), - &config->dmic.pdm[j], + &config->dai_data[0].dmic.pdm[j], sizeof( struct sof_ipc_dai_dmic_pdm_ctrl)); assert(!ret); @@ -1156,8 +1158,8 @@ static int dmic_set_config(struct dai *dai, struct sof_ipc_dai_config *config) } } - trace_dmic_id(dai, "dmic_set_config(), prm config->dmic.num_pdm_active = %u", - config->dmic.num_pdm_active); + trace_dmic_id(dai, "dmic_set_config(), prm config->dai_data[0].dmic.num_pdm_active = %u", + config->dai_data[0].dmic.num_pdm_active); trace_dmic_id(dai, "dmic_set_config(), prm pdmclk_min = %u, pdmclk_max = %u", dmic_prm[di]->pdmclk_min, dmic_prm[di]->pdmclk_max); trace_dmic_id(dai, "dmic_set_config(), prm duty_min = %u, duty_max = %u", diff --git a/src/drivers/intel/cavs/ssp.c b/src/drivers/intel/cavs/ssp.c index 2995c1a42500..586fce93f759 100644 --- a/src/drivers/intel/cavs/ssp.c +++ b/src/drivers/intel/cavs/ssp.c @@ -160,7 +160,7 @@ static int ssp_set_config(struct dai *dai, sspsp = 0; ssp->config = *config; - ssp->params = config->ssp; + ssp->params = config->dai_data[0].ssp; /* sspsp2 no dynamic setting */ sspsp2 = 0x0; @@ -172,10 +172,10 @@ static int ssp_set_config(struct dai *dai, ssto = 0x0; /* sstsa dynamic setting is TTSA, default 2 slots */ - sstsa = config->ssp.tx_slots; + sstsa = config->dai_data[0].ssp.tx_slots; /* ssrsa dynamic setting is RTSA, default 2 slots */ - ssrsa = config->ssp.rx_slots; + ssrsa = config->dai_data[0].ssp.rx_slots; switch (config->format & SOF_DAI_FMT_MASTER_MASK) { case SOF_DAI_FMT_CBM_CFM: @@ -275,39 +275,45 @@ static int ssp_set_config(struct dai *dai, sscr2 |= (ssp->params.quirks & SOF_DAI_INTEL_SSP_QUIRK_PSPSRWFDFD) ? SSCR2_PSPSRWFDFD : 0; - if (!config->ssp.mclk_rate || - config->ssp.mclk_rate > ssp_freq[MAX_SSP_FREQ_INDEX].freq) { + if (!config->dai_data[0].ssp.mclk_rate || + config->dai_data[0].ssp.mclk_rate > + ssp_freq[MAX_SSP_FREQ_INDEX].freq) { trace_ssp_error("ssp_set_config() error: " "invalid MCLK = %d Hz (valid < %d)", - config->ssp.mclk_rate, + config->dai_data[0].ssp.mclk_rate, ssp_freq[MAX_SSP_FREQ_INDEX].freq); ret = -EINVAL; goto out; } - if (!config->ssp.bclk_rate || - config->ssp.bclk_rate > config->ssp.mclk_rate) { + if (!config->dai_data[0].ssp.bclk_rate || + config->dai_data[0].ssp.bclk_rate > + config->dai_data[0].ssp.mclk_rate) { trace_ssp_error("ssp_set_config() error: " "BCLK %d Hz = 0 or > MCLK %d Hz", - config->ssp.bclk_rate, config->ssp.mclk_rate); + config->dai_data[0].ssp.bclk_rate, + config->dai_data[0].ssp.mclk_rate); ret = -EINVAL; goto out; } /* MCLK config */ - ret = mn_set_mclk(config->ssp.mclk_id, config->ssp.mclk_rate); + ret = mn_set_mclk(config->dai_data[0].ssp.mclk_id, + config->dai_data[0].ssp.mclk_rate); if (ret < 0) { trace_ssp_error("error: invalid mclk_rate = %d for mclk_id = %d", - config->ssp.mclk_id, config->ssp.mclk_rate); + config->dai_data[0].ssp.mclk_id, + config->dai_data[0].ssp.mclk_rate); goto out; } /* BCLK config */ - ret = mn_set_bclk(config->dai_index, config->ssp.bclk_rate, + ret = mn_set_bclk(config->dai_index, config->dai_data[0].ssp.bclk_rate, &mdiv, &need_ecs); if (ret < 0) { trace_ssp_error("error: invalid bclk_rate = %d for dai_index = %d", - config->ssp.bclk_rate, config->dai_index); + config->dai_data[0].ssp.bclk_rate, + config->dai_index); goto out; } @@ -329,35 +335,40 @@ static int ssp_set_config(struct dai *dai, sscr0 |= SSCR0_SCR(mdiv); /* calc frame width based on BCLK and rate - must be divisable */ - if (config->ssp.bclk_rate % config->ssp.fsync_rate) { + if (config->dai_data[0].ssp.bclk_rate % + config->dai_data[0].ssp.fsync_rate) { trace_ssp_error("ssp_set_config() error: " "BCLK %d is not divisable by rate %d", - config->ssp.bclk_rate, config->ssp.fsync_rate); + config->dai_data[0].ssp.bclk_rate, + config->dai_data[0].ssp.fsync_rate); ret = -EINVAL; goto out; } /* must be enough BCLKs for data */ - bdiv = config->ssp.bclk_rate / config->ssp.fsync_rate; - if (bdiv < config->ssp.tdm_slot_width * config->ssp.tdm_slots) { + bdiv = config->dai_data[0].ssp.bclk_rate / + config->dai_data[0].ssp.fsync_rate; + if (bdiv < config->dai_data[0].ssp.tdm_slot_width * config->dai_data[0].ssp.tdm_slots) { trace_ssp_error("ssp_set_config() error: not enough BCLKs " - "need %d", config->ssp.tdm_slot_width * - config->ssp.tdm_slots); + "need %d", + config->dai_data[0].ssp.tdm_slot_width * + config->dai_data[0].ssp.tdm_slots); ret = -EINVAL; goto out; } /* tdm_slot_width must be <= 38 for SSP */ - if (config->ssp.tdm_slot_width > 38) { + if (config->dai_data[0].ssp.tdm_slot_width > 38) { trace_ssp_error("ssp_set_config() error: tdm_slot_width %d > " - "38", config->ssp.tdm_slot_width); + "38", config->dai_data[0].ssp.tdm_slot_width); ret = -EINVAL; goto out; } - bdiv_min = config->ssp.tdm_slots * - (config->ssp.tdm_per_slot_padding_flag ? - config->ssp.tdm_slot_width : config->ssp.sample_valid_bits); + bdiv_min = config->dai_data[0].ssp.tdm_slots * + (config->dai_data[0].ssp.tdm_per_slot_padding_flag ? + config->dai_data[0].ssp.tdm_slot_width : + config->dai_data[0].ssp.sample_valid_bits); if (bdiv < bdiv_min) { trace_ssp_error("ssp_set_config() error: bdiv(%d) < " "bdiv_min(%d)", bdiv, bdiv_min); @@ -379,7 +390,7 @@ static int ssp_set_config(struct dai *dai, start_delay = true; - sscr0 |= SSCR0_FRDC(config->ssp.tdm_slots); + sscr0 |= SSCR0_FRDC(config->dai_data[0].ssp.tdm_slots); if (bdiv % 2) { trace_ssp_error("ssp_set_config() error: " @@ -433,7 +444,7 @@ static int ssp_set_config(struct dai *dai, /* default start_delay value is set to false */ - sscr0 |= SSCR0_FRDC(config->ssp.tdm_slots); + sscr0 |= SSCR0_FRDC(config->dai_data[0].ssp.tdm_slots); /* LJDFD enable */ sscr2 &= ~SSCR2_LJDFD; @@ -495,7 +506,8 @@ static int ssp_set_config(struct dai *dai, /* default start_delay value is set to false */ - sscr0 |= SSCR0_MOD | SSCR0_FRDC(config->ssp.tdm_slots); + sscr0 |= SSCR0_MOD | + SSCR0_FRDC(config->dai_data[0].ssp.tdm_slots); /* set asserted frame length */ frame_len = 1; /* default */ @@ -524,8 +536,8 @@ static int ssp_set_config(struct dai *dai, */ sspsp |= SSPSP_SFRMP(!inverted_frame); - active_tx_slots = popcount(config->ssp.tx_slots); - active_rx_slots = popcount(config->ssp.rx_slots); + active_tx_slots = popcount(config->dai_data[0].ssp.tx_slots); + active_rx_slots = popcount(config->dai_data[0].ssp.rx_slots); /* * handle TDM mode, TDM mode has padding at the end of @@ -533,11 +545,12 @@ static int ssp_set_config(struct dai *dai, * subtracting slot width and valid bits per slot. */ if (ssp->params.tdm_per_slot_padding_flag) { - frame_end_padding = bdiv - config->ssp.tdm_slots * - config->ssp.tdm_slot_width; + frame_end_padding = bdiv - + config->dai_data[0].ssp.tdm_slots * + config->dai_data[0].ssp.tdm_slot_width; - slot_end_padding = config->ssp.tdm_slot_width - - config->ssp.sample_valid_bits; + slot_end_padding = config->dai_data[0].ssp.tdm_slot_width - + config->dai_data[0].ssp.sample_valid_bits; if (slot_end_padding > SOF_DAI_INTEL_SSP_SLOT_PADDING_MAX) { @@ -571,7 +584,7 @@ static int ssp_set_config(struct dai *dai, sspsp |= SSPSP_SFRMWDTH(frame_len); - data_size = config->ssp.sample_valid_bits; + data_size = config->dai_data[0].ssp.sample_valid_bits; if (data_size > 16) sscr0 |= (SSCR0_EDSS | SSCR0_DSIZE(data_size - 16)); @@ -579,7 +592,7 @@ static int ssp_set_config(struct dai *dai, sscr0 |= SSCR0_DSIZE(data_size); /* setting TFT and RFT */ - switch (config->ssp.sample_valid_bits) { + switch (config->dai_data[0].ssp.sample_valid_bits) { case 16: /* use 2 bytes for each slot */ sample_width = 2; @@ -592,7 +605,7 @@ static int ssp_set_config(struct dai *dai, default: trace_ssp_error("ssp_set_config() error: " "sample_valid_bits %d", - config->ssp.sample_valid_bits); + config->dai_data[0].ssp.sample_valid_bits); ret = -EINVAL; goto out; } @@ -790,7 +803,7 @@ static int ssp_remove(struct dai *dai) pm_runtime_put_sync(SSP_CLK, dai->index); - mn_release_mclk(ssp->config.ssp.mclk_id); + mn_release_mclk(ssp->config.dai_data[0].ssp.mclk_id); mn_release_bclk(dai->index); /* Disable SSP power */ diff --git a/src/include/ipc/dai-imx.h b/src/include/ipc/dai-imx.h index 59ec4b400efa..7f9d17c796a8 100644 --- a/src/include/ipc/dai-imx.h +++ b/src/include/ipc/dai-imx.h @@ -13,7 +13,8 @@ /* ESAI Configuration Request - SOF_IPC_DAI_ESAI_CONFIG */ struct sof_ipc_dai_esai_params { - uint32_t reserved0[2]; + uint32_t subdai_index; /* only used in multi-dai usages */ + uint32_t reserved0; /* MCLK */ uint16_t reserved1; @@ -32,7 +33,8 @@ struct sof_ipc_dai_esai_params { /* SAI Configuration Request - SOF_IPC_DAI_SAI_CONFIG */ struct sof_ipc_dai_sai_params { - uint32_t reserved0[2]; + uint32_t subdai_index; /* only used in multi-dai usages */ + uint32_t reserved0; /* MCLK */ uint16_t reserved1; diff --git a/src/include/ipc/dai-intel.h b/src/include/ipc/dai-intel.h index fc0da0c745d0..ab7d8e10effc 100644 --- a/src/include/ipc/dai-intel.h +++ b/src/include/ipc/dai-intel.h @@ -59,7 +59,8 @@ /* SSP Configuration Request - SOF_IPC_DAI_SSP_CONFIG */ struct sof_ipc_dai_ssp_params { - uint32_t reserved0[2]; + uint32_t subdai_index; /* only used in multi-dai usages */ + uint32_t reserved0; uint16_t reserved1; uint16_t mclk_id; @@ -91,13 +92,15 @@ struct sof_ipc_dai_ssp_params { /* HDA Configuration Request - SOF_IPC_DAI_HDA_CONFIG */ struct sof_ipc_dai_hda_params { - uint32_t reserved0[2]; + uint32_t subdai_index; /* only used in multi-dai usages */ + uint32_t reserved0; uint32_t link_dma_ch; } __attribute__((packed)); /* ALH Configuration Request - SOF_IPC_DAI_ALH_CONFIG */ struct sof_ipc_dai_alh_params { - uint32_t reserved0[2]; + uint32_t subdai_index; /* only used in multi-dai usages */ + uint32_t reserved0; uint32_t stream_id; /* reserved for future use */ @@ -169,7 +172,8 @@ struct sof_ipc_dai_dmic_pdm_ctrl { * treated as an error. */ struct sof_ipc_dai_dmic_params { - uint32_t reserved0[2]; + 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/src/include/ipc/dai.h b/src/include/ipc/dai.h index 50f986f54baa..c5cf6108826f 100644 --- a/src/include/ipc/dai.h +++ b/src/include/ipc/dai.h @@ -16,6 +16,7 @@ #ifndef __IPC_DAI_H__ #define __IPC_DAI_H__ +#include #include #include #include @@ -61,20 +62,28 @@ enum sof_ipc_dai_type { 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 { @@ -84,7 +93,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; } __attribute__((packed)); #endif /* __IPC_DAI_H__ */