sample_valid_bits remains in main structure for now since it is handled with a generic dai token.
Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com --- src/audio/dai.c | 28 ++++++++++++++++++---------- src/drivers/apl-ssp.c | 34 +++++++++++++++++----------------- src/drivers/byt-ssp.c | 42 +++++++++++++++++++++--------------------- src/include/uapi/ipc.h | 47 ++++++++++++++++++++++++----------------------- 4 files changed, 80 insertions(+), 71 deletions(-)
diff --git a/src/audio/dai.c b/src/audio/dai.c index 576914c..1c50c08 100644 --- a/src/audio/dai.c +++ b/src/audio/dai.c @@ -622,18 +622,26 @@ static int dai_config(struct comp_dev *dev, struct sof_ipc_dai_config *config) { struct dai_data *dd = comp_get_drvdata(dev);
- /* set dma burst elems to slot number */ - dd->config.burst_elems = config->tdm_slots; - - /* calc frame bytes */ - switch (config->sample_valid_bits) { - case 16: - dev->frame_bytes = 2 * config->tdm_slots; - break; - case 17 ... 32: - dev->frame_bytes = 4 * config->tdm_slots; + switch (config->type) { + case SOF_DAI_INTEL_SSP: + /* set dma burst elems to slot number */ + dd->config.burst_elems = config->ssp.tdm_slots; + + /* calc frame bytes */ + switch (config->sample_valid_bits) { + case 16: + dev->frame_bytes = 2 * config->ssp.tdm_slots; + break; + case 17 ... 32: + dev->frame_bytes = 4 * config->ssp.tdm_slots; + break; + default: + break; + } break; default: + /* other types of DAIs not handled for now */ + trace_dai_error("de2"); break; }
diff --git a/src/drivers/apl-ssp.c b/src/drivers/apl-ssp.c index ac46b80..0153b7c 100644 --- a/src/drivers/apl-ssp.c +++ b/src/drivers/apl-ssp.c @@ -168,10 +168,10 @@ static inline int ssp_set_config(struct dai *dai, ssto = 0x0;
/* sstsa dynamic setting is TTSA, default 2 slots */ - sstsa = config->tx_slots; + sstsa = config->ssp.tx_slots;
/* ssrsa dynamic setting is RTSA, default 2 slots */ - ssrsa = config->rx_slots; + ssrsa = config->ssp.rx_slots;
/* clock masters */ sscr1 &= ~SSCR1_SFRMDIR; @@ -259,14 +259,14 @@ static inline int ssp_set_config(struct dai *dai, #endif
/* BCLK is generated from MCLK - must be divisable */ - if (config->mclk_rate % config->bclk_rate) { + if (config->ssp.mclk_rate % config->ssp.bclk_rate) { trace_ssp_error("ec5"); ret = -EINVAL; goto out; }
/* divisor must be within SCR range */ - mdiv = (config->mclk_rate / config->bclk_rate) - 1; + mdiv = (config->ssp.mclk_rate / config->ssp.bclk_rate) - 1; if (mdiv > (SSCR0_SCR_MASK >> 8)) { trace_ssp_error("ec6"); ret = -EINVAL; @@ -277,7 +277,7 @@ static inline int ssp_set_config(struct dai *dai, sscr0 |= SSCR0_SCR(mdiv);
/* calc frame width based on BCLK and rate - must be divisable */ - if (config->bclk_rate % config->fsync_rate) { + if (config->ssp.bclk_rate % config->ssp.fsync_rate) { trace_ssp_error("ec7"); ret = -EINVAL; goto out; @@ -285,15 +285,15 @@ static inline int ssp_set_config(struct dai *dai,
/* must be enough BCLKs for data */ - bdiv = config->bclk_rate / config->fsync_rate; - if (bdiv < config->tdm_slot_width * config->tdm_slots) { + bdiv = config->ssp.bclk_rate / config->ssp.fsync_rate; + if (bdiv < config->ssp.tdm_slot_width * config->ssp.tdm_slots) { trace_ssp_error("ec8"); ret = -EINVAL; goto out; }
/* tdm_slot_width must be <= 38 for SSP */ - if (config->tdm_slot_width > 38) { + if (config->ssp.tdm_slot_width > 38) { trace_ssp_error("ec9"); ret = -EINVAL; goto out; @@ -305,7 +305,7 @@ static inline int ssp_set_config(struct dai *dai,
start_delay = 1;
- sscr0 |= SSCR0_FRDC(config->tdm_slots); + sscr0 |= SSCR0_FRDC(config->ssp.tdm_slots);
if (bdiv % 2) { trace_ssp_error("eca"); @@ -331,7 +331,7 @@ static inline int ssp_set_config(struct dai *dai,
start_delay = 0;
- sscr0 |= SSCR0_FRDC(config->tdm_slots); + sscr0 |= SSCR0_FRDC(config->ssp.tdm_slots);
/* LJDFD enable */ sscr2 &= ~SSCR2_LJDFD; @@ -358,7 +358,7 @@ static inline int ssp_set_config(struct dai *dai,
start_delay = 0;
- sscr0 |= SSCR0_MOD | SSCR0_FRDC(config->tdm_slots); + sscr0 |= SSCR0_MOD | SSCR0_FRDC(config->ssp.tdm_slots);
/* set asserted frame length */ frame_len = 1; @@ -372,15 +372,15 @@ static inline int ssp_set_config(struct dai *dai, sspsp |= SSPSP_SFRMP(!inverted_frame); sspsp |= SSPSP_FSRT;
- active_tx_slots = hweight_32(config->tx_slots); - active_rx_slots = hweight_32(config->rx_slots); + active_tx_slots = hweight_32(config->ssp.tx_slots); + active_rx_slots = hweight_32(config->ssp.rx_slots);
break; case SOF_DAI_FMT_DSP_B:
start_delay = 0;
- sscr0 |= SSCR0_MOD | SSCR0_FRDC(config->tdm_slots); + sscr0 |= SSCR0_MOD | SSCR0_FRDC(config->ssp.tdm_slots);
/* set asserted frame length */ frame_len = 1; @@ -393,8 +393,8 @@ static inline int ssp_set_config(struct dai *dai, */ sspsp |= SSPSP_SFRMP(!inverted_frame);
- active_tx_slots = hweight_32(config->tx_slots); - active_rx_slots = hweight_32(config->rx_slots); + active_tx_slots = hweight_32(config->ssp.tx_slots); + active_rx_slots = hweight_32(config->ssp.rx_slots);
break; default: @@ -406,7 +406,7 @@ static inline int ssp_set_config(struct dai *dai, sspsp |= SSPSP_STRTDLY(start_delay); sspsp |= SSPSP_SFRMWDTH(frame_len);
- bdiv_min = config->tdm_slots * config->sample_valid_bits; + bdiv_min = config->ssp.tdm_slots * config->sample_valid_bits; if (bdiv < bdiv_min) { trace_ssp_error("ecc"); ret = -EINVAL; diff --git a/src/drivers/byt-ssp.c b/src/drivers/byt-ssp.c index c8a4f31..a9e77df 100644 --- a/src/drivers/byt-ssp.c +++ b/src/drivers/byt-ssp.c @@ -264,14 +264,14 @@ static inline int ssp_set_config(struct dai *dai, #endif
/* BCLK is generated from MCLK - must be divisable */ - if (config->mclk_rate % config->bclk_rate) { + if (config->ssp.mclk_rate % config->ssp.bclk_rate) { trace_ssp_error("ec5"); ret = -EINVAL; goto out; }
/* divisor must be within SCR range */ - mdiv = (config->mclk_rate / config->bclk_rate) - 1; + mdiv = (config->ssp.mclk_rate / config->ssp.bclk_rate) - 1; if (mdiv > (SSCR0_SCR_MASK >> 8)) { trace_ssp_error("ec6"); ret = -EINVAL; @@ -282,23 +282,23 @@ static inline int ssp_set_config(struct dai *dai, sscr0 |= SSCR0_SCR(mdiv);
/* calc frame width based on BCLK and rate - must be divisable */ - if (config->bclk_rate % config->fsync_rate) { + if (config->ssp.bclk_rate % config->ssp.fsync_rate) { trace_ssp_error("ec7"); ret = -EINVAL; goto out; }
/* must be enouch BCLKs for data */ - bdiv = config->bclk_rate / config->fsync_rate; - if (bdiv < config->tdm_slot_width * - config->tdm_slots) { + bdiv = config->ssp.bclk_rate / config->ssp.fsync_rate; + if (bdiv < config->ssp.tdm_slot_width * + config->ssp.tdm_slots) { trace_ssp_error("ec8"); ret = -EINVAL; goto out; }
/* tdm_slot_width must be <= 38 for SSP */ - if (config->tdm_slot_width > 38) { + if (config->ssp.tdm_slot_width > 38) { trace_ssp_error("ec9"); ret = -EINVAL; goto out; @@ -314,7 +314,7 @@ static inline 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->tdm_slot_width; + frame_len = config->ssp.tdm_slot_width;
/* handle frame polarity, I2S default is falling/active low */ sspsp |= SSPSP_SFRMP(!inverted_frame); @@ -344,7 +344,7 @@ static inline 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->tdm_slot_width; + frame_len = config->ssp.tdm_slot_width;
/* LEFT_J default is rising/active high, opposite of I2S */ sspsp |= SSPSP_SFRMP(inverted_frame); @@ -369,7 +369,7 @@ static inline int ssp_set_config(struct dai *dai,
start_delay = 1;
- sscr0 |= SSCR0_MOD | SSCR0_FRDC(config->tdm_slots); + sscr0 |= SSCR0_MOD | SSCR0_FRDC(config->ssp.tdm_slots);
/* set asserted frame length */ frame_len = 1; @@ -386,18 +386,18 @@ static inline int ssp_set_config(struct dai *dai, * deasserted time of frame) */ if (cbs) - sscr4 |= SSCR4_TOT_FRM_PRD(config->tdm_slots * - config->tdm_slot_width); + sscr4 |= SSCR4_TOT_FRM_PRD(config->ssp.tdm_slots * + config->ssp.tdm_slot_width);
- active_tx_slots = hweight_32(config->tx_slots); - active_rx_slots = hweight_32(config->rx_slots); + active_tx_slots = hweight_32(config->ssp.tx_slots); + active_rx_slots = hweight_32(config->ssp.rx_slots);
break; case SOF_DAI_FMT_DSP_B:
start_delay = 0;
- sscr0 |= SSCR0_MOD | SSCR0_FRDC(config->tdm_slots); + sscr0 |= SSCR0_MOD | SSCR0_FRDC(config->ssp.tdm_slots);
/* set asserted frame length */ frame_len = 1; @@ -414,11 +414,11 @@ static inline int ssp_set_config(struct dai *dai, * deasserted time of frame */ if (cbs) - sscr4 |= SSCR4_TOT_FRM_PRD(config->tdm_slots * - config->tdm_slot_width); + sscr4 |= SSCR4_TOT_FRM_PRD(config->ssp.tdm_slots * + config->ssp.tdm_slot_width);
- active_tx_slots = hweight_32(config->tx_slots); - active_rx_slots = hweight_32(config->rx_slots); + active_tx_slots = hweight_32(config->ssp.tx_slots); + active_rx_slots = hweight_32(config->ssp.rx_slots);
break; default: @@ -454,8 +454,8 @@ static inline 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->tx_slots); - ssp_write(dai, SSRSA, config->rx_slots); + ssp_write(dai, SSTSA, config->ssp.tx_slots); + ssp_write(dai, SSRSA, config->ssp.rx_slots);
ssp->state[DAI_DIR_PLAYBACK] = COMP_STATE_PREPARE; ssp->state[DAI_DIR_CAPTURE] = COMP_STATE_PREPARE; diff --git a/src/include/uapi/ipc.h b/src/include/uapi/ipc.h index 9a22c69..a2e0199 100644 --- a/src/include/uapi/ipc.h +++ b/src/include/uapi/ipc.h @@ -231,6 +231,30 @@ struct sof_ipc_dai_ssp_params { struct sof_ipc_hdr hdr; uint16_t mode; // FIXME: do we need this? uint16_t clk_id; // FIXME: do we need this? + + uint32_t mclk_rate; /* mclk frequency in Hz */ + uint32_t fsync_rate; /* fsync frequency in Hz */ + uint32_t bclk_rate; /* bclk frequency in Hz */ + + /* TDM */ + uint32_t tdm_slots; + uint32_t rx_slots; + uint32_t tx_slots; + + /* data */ + uint16_t tdm_slot_width; + uint16_t reserved2; /* alignment */ + + /* MCLK */ + uint32_t mclk_direction; + uint32_t mclk_keep_active; + uint32_t bclk_keep_active; + uint32_t fs_keep_active; + + //uint32_t quirks; // FIXME: is 32 bits enough ? + + /* private data, e.g. for quirks */ + //uint32_t pdata[10]; // FIXME: would really need ~16 u32 } __attribute__((packed));
/* HDA Configuration Request - SOF_IPC_DAI_HDA_CONFIG */ @@ -255,30 +279,7 @@ struct sof_ipc_dai_config { uint16_t format; /* SOF_DAI_FMT_ */ uint16_t reserved; /* alignment */
- uint32_t mclk_rate; /* mclk frequency in Hz */ - uint32_t fsync_rate; /* fsync frequency in Hz */ - uint32_t bclk_rate; /* bclk frequency in Hz */ - - /* TDM */ - uint32_t tdm_slots; - uint32_t rx_slots; - uint32_t tx_slots; - - /* data */ uint32_t sample_valid_bits; - uint16_t tdm_slot_width; - uint16_t reserved2; /* alignment */ - - /* MCLK */ - uint32_t mclk_direction; - uint32_t mclk_keep_active; - uint32_t bclk_keep_active; - uint32_t fs_keep_active; - - //uint32_t quirks; // FIXME: is 32 bits enough ? - - /* private data, e.g. for quirks */ - //uint32_t pdata[10]; // FIXME: would really need ~16 u32
/* HW specific data */ union {