[Sound-open-firmware] [PATCH v2 0/7] SSP: baytrail 24 bits support
This series is created to change the SSP format setting for both Tx and Rx, and it is verified on MinnowMax + ALC5651 codec with I2S stereo both SSP_CLK_EXT and SSP_CLK_AUDIO mode. Changes including: 1. change ssp clock from 25M to 19.2M; 2. add 16bit <==> 24bit volume converting functions; 3. change to get dai format from host; 4. change to get ssp stream format from host; 5. remove the shim SSP divider and use SSCR0.SCR for BCLK generating.
changes from v1: 1. change to make dai format configurable; 2. change to make ssp stream format configurable; 3. clean shim SSP divider code; 4. optimize volume copy functions.
Keyon Jie (7): ssp: switch to use SCR for BCLK generation. platform: switch default ssp clock to 19.2M volume: add 16bit<==>24bit volume copy function and mapping ssp: switch dai format form PCM B mode to normal I2S mode intel-ipc: get dai format from ipc dai: add stream_format to dai_data for codec stream intel-ipc: change to get ssp stream format from ipc
src/audio/dai.c | 10 ++ src/audio/volume.c | 119 ++++++++++++--------- src/drivers/ssp.c | 5 +- src/include/reef/dai.h | 1 + src/include/reef/stream.h | 20 ++++ src/include/uapi/intel-ipc.h | 2 + src/ipc/intel-ipc.c | 32 +++--- src/platform/baytrail/include/platform/platform.h | 10 +- src/platform/baytrail/platform.c | 120 ---------------------- 9 files changed, 126 insertions(+), 193 deletions(-)
switch the BCLK generation from shim ssp clock divider to using SSCR0.SCR, as the divider may lead to jitter.
clear and remove M/N divider part code.
Signed-off-by: Keyon Jie yang.jie@linux.intel.com --- src/drivers/ssp.c | 5 +- src/ipc/intel-ipc.c | 10 -- src/platform/baytrail/include/platform/platform.h | 5 - src/platform/baytrail/platform.c | 115 ---------------------- 4 files changed, 1 insertion(+), 134 deletions(-)
diff --git a/src/drivers/ssp.c b/src/drivers/ssp.c index 77341b6..9656104 100644 --- a/src/drivers/ssp.c +++ b/src/drivers/ssp.c @@ -221,7 +221,6 @@ static inline int ssp_set_config(struct dai *dai, struct dai_config *dai_config) /* clock signal polarity */ switch (dai->config.format & DAI_FMT_INV_MASK) { case DAI_FMT_NB_NF: - sspsp |= SSPSP_SFRMP; break; case DAI_FMT_NB_IF: break; @@ -253,9 +252,7 @@ static inline int ssp_set_config(struct dai *dai, struct dai_config *dai_config) return -ENODEV; }
- /* TODO: clock frequency */ - //scr = dai_config->mclk / ( - + sscr0 |= SSCR0_SCR(dai->config.mclk_fs / dai->config.bclk_fs - 1); /* format */ switch (dai->config.format & DAI_FMT_FORMAT_MASK) { case DAI_FMT_I2S: diff --git a/src/ipc/intel-ipc.c b/src/ipc/intel-ipc.c index 7aa24f3..1fdd73f 100644 --- a/src/ipc/intel-ipc.c +++ b/src/ipc/intel-ipc.c @@ -530,7 +530,6 @@ static uint32_t ipc_device_set_formats(uint32_t header) { struct ipc_intel_ipc_device_config_req config_req; struct ipc_dai_dev *dai_dev; - int err;
trace_ipc("DsF");
@@ -569,15 +568,6 @@ static uint32_t ipc_device_set_formats(uint32_t header) dai_dev->dai_config.mclk_fs = 256; dai_dev->dai_config.clk_src = SSP_CLK_EXT;
- /* set SSP M/N dividers */ - err = platform_ssp_set_mn(config_req.ssp_interface, - 25000000, 48000, - dai_dev->dai_config.bclk_fs); - if (err < 0) { - trace_ipc_error("eDs"); - goto error; - } - comp_dai_config(dai_dev->dev.cd, &dai_dev->dai_config);
error: diff --git a/src/platform/baytrail/include/platform/platform.h b/src/platform/baytrail/include/platform/platform.h index 38fcc26..bbf16d5 100644 --- a/src/platform/baytrail/include/platform/platform.h +++ b/src/platform/baytrail/include/platform/platform.h @@ -88,9 +88,4 @@ int platform_boot_complete(uint32_t boot_message);
int platform_init(void);
-int platform_ssp_set_mn(uint32_t ssp_port, uint32_t source, uint32_t rate, - uint32_t bclk_fs); - -void platform_ssp_disable_mn(uint32_t ssp_port); - #endif diff --git a/src/platform/baytrail/platform.c b/src/platform/baytrail/platform.c index ea3828f..607fced 100644 --- a/src/platform/baytrail/platform.c +++ b/src/platform/baytrail/platform.c @@ -89,121 +89,6 @@ int platform_boot_complete(uint32_t boot_message) return 0; }
-struct ssp_mn { - uint32_t source; - uint32_t bclk_fs; - uint32_t rate; - uint32_t m; - uint32_t n; -}; - -/* TODO: move over to the PLL instead of M/N */ -static const struct ssp_mn ssp_mn_conf[] = { - {25000000, 24, 48000, 1152, 25000}, /* 1.152MHz */ - {25000000, 32, 48000, 1536, 25000}, /* 1.536MHz */ - {25000000, 64, 48000, 3072, 25000}, /* 3.072MHz */ - {25000000, 400, 48000, 96, 125}, /* 19.2MHz */ - {25000000, 400, 44100, 441, 625}, /* 17.64MHz */ - {19200000, 24, 48000, 3, 50}, /* 1.152MHz */ - {19200000, 32, 48000, 2, 25}, /* 1.536MHz */ - {19200000, 64, 48000, 4, 25}, /* 3.072MHz */ - {19200000, 400, 44100, 441, 480}, /* 17.64MHz */ -}; - -/* set the SSP M/N clock dividers */ -int platform_ssp_set_mn(uint32_t ssp_port, uint32_t source, uint32_t rate, - uint32_t bclk_fs) -{ - int i; - - /* check for matching config in the table */ - for (i = 0; i < ARRAY_SIZE(ssp_mn_conf); i++) { - - if (ssp_mn_conf[i].source != source) - continue; - - if (ssp_mn_conf[i].rate != rate) - continue; - - if (ssp_mn_conf[i].bclk_fs != bclk_fs) - continue; - - /* match */ - switch (ssp_port) { - case 0: - shim_write(SHIM_SSP0_DIVL, ssp_mn_conf[i].n); - shim_write(SHIM_SSP0_DIVH, SHIM_SSP_DIV_ENA | - SHIM_SSP_DIV_UPD | ssp_mn_conf[i].m); - break; - case 1: - shim_write(SHIM_SSP1_DIVL, ssp_mn_conf[i].n); - shim_write(SHIM_SSP1_DIVH, SHIM_SSP_DIV_ENA | - SHIM_SSP_DIV_UPD | ssp_mn_conf[i].m); - break; - case 2: - shim_write(SHIM_SSP2_DIVL, ssp_mn_conf[i].n); - shim_write(SHIM_SSP2_DIVH, SHIM_SSP_DIV_ENA | - SHIM_SSP_DIV_UPD | ssp_mn_conf[i].m); - break; -#if defined CONFIG_CHERRYTRAIL - case 3: - shim_write(SHIM_SSP3_DIVL, ssp_mn_conf[i].n); - shim_write(SHIM_SSP3_DIVH, SHIM_SSP_DIV_ENA | - SHIM_SSP_DIV_UPD | ssp_mn_conf[i].m); - break; - case 4: - shim_write(SHIM_SSP4_DIVL, ssp_mn_conf[i].n); - shim_write(SHIM_SSP4_DIVH, SHIM_SSP_DIV_ENA | - SHIM_SSP_DIV_UPD | ssp_mn_conf[i].m); - break; - case 5: - shim_write(SHIM_SSP5_DIVL, ssp_mn_conf[i].n); - shim_write(SHIM_SSP5_DIVH, SHIM_SSP_DIV_ENA | - SHIM_SSP_DIV_UPD | ssp_mn_conf[i].m); - break; -#endif - default: - return -ENODEV; - } - - return 0; - } - - return -EINVAL; -} - -void platform_ssp_disable_mn(uint32_t ssp_port) -{ - switch (ssp_port) { - case 0: - shim_write(SHIM_SSP0_DIVH, SHIM_SSP_DIV_BYP | - SHIM_SSP_DIV_UPD); - break; - case 1: - shim_write(SHIM_SSP1_DIVH, SHIM_SSP_DIV_BYP | - SHIM_SSP_DIV_UPD); - break; - case 2: - shim_write(SHIM_SSP2_DIVH, SHIM_SSP_DIV_BYP | - SHIM_SSP_DIV_UPD); - break; -#if defined CONFIG_CHERRYTRAIL - case 3: - shim_write(SHIM_SSP3_DIVH, SHIM_SSP_DIV_BYP | - SHIM_SSP_DIV_UPD); - break; - case 4: - shim_write(SHIM_SSP4_DIVH, SHIM_SSP_DIV_BYP | - SHIM_SSP_DIV_UPD); - break; - case 5: - shim_write(SHIM_SSP5_DIVH, SHIM_SSP_DIV_BYP | - SHIM_SSP_DIV_UPD); - break; -#endif - } -} - /* clear mask in PISR, bits are W1C in docs but some bits need preserved ?? */ void platform_interrupt_clear(uint32_t irq, uint32_t mask) {
switch default ssp clock from 25M to 19.2M, which may help for 24 bit format.
Signed-off-by: Keyon Jie yang.jie@linux.intel.com --- src/platform/baytrail/platform.c | 5 ----- 1 file changed, 5 deletions(-)
diff --git a/src/platform/baytrail/platform.c b/src/platform/baytrail/platform.c index 607fced..ed7f108 100644 --- a/src/platform/baytrail/platform.c +++ b/src/platform/baytrail/platform.c @@ -180,13 +180,8 @@ int platform_init(void)
trace_point(TRACE_BOOT_PLATFORM_SSP_FREQ);
-#if defined CONFIG_BAYTRAIL - /* set SSP clock to 25M TODO: make BYT use 19.2M as default */ - clock_set_freq(CLK_SSP, 25000000); -#elif defined CONFIG_CHERRYTRAIL /* set SSP clock to 19.2M */ clock_set_freq(CLK_SSP, 19200000); -#endif
/* initialise the host IPC mechanisms */ trace_point(TRACE_BOOT_PLATFORM_IPC);
add 16bit<==>24bit volume copy function and mapping, for 24 bits ssp output/input.
here also optimize all other volume copy functions.
Signed-off-by: Keyon Jie yang.jie@linux.intel.com --- src/audio/volume.c | 119 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 71 insertions(+), 48 deletions(-)
diff --git a/src/audio/volume.c b/src/audio/volume.c index f5528cd..04ac34a 100644 --- a/src/audio/volume.c +++ b/src/audio/volume.c @@ -75,6 +75,7 @@ struct comp_data { struct comp_func_map { uint16_t source; /* source format */ uint16_t sink; /* sink format */ + uint16_t channels; /* channel number for the stream */ void (*func)(struct comp_dev *dev, struct comp_buffer *sink, struct comp_buffer *source, uint32_t frames); }; @@ -85,21 +86,16 @@ static void vol_s16_to_s32(struct comp_dev *dev, struct comp_buffer *sink, { struct comp_data *cd = comp_get_drvdata(dev); int16_t *src = (int16_t*) source->r_ptr; - int32_t *dest = (int32_t*) sink->w_ptr; - int i, j; + int32_t i, *dest = (int32_t*) sink->w_ptr;
/* buffer sizes are always divisible by period frames */ - for (i = 0; i < frames; i++) { - for (j = 0; j < source->params.channels; j++) { - int32_t val = (int32_t)*src; - *dest = (val * cd->volume[j]) >> 16; - dest++; - src++; - } + for (i = 0; i < frames * 2; i += 2) { + dest[i] = (int32_t)src[i] * cd->volume[0]; + dest[i + 1] = (int32_t)src[i] * cd->volume[1]; }
- source->r_ptr = src; - sink->w_ptr = dest; + source->r_ptr = src + i; + sink->w_ptr = dest + i; }
/* copy and scale volume from 32 bit source buffer to 16 bit dest buffer */ @@ -107,22 +103,17 @@ static void vol_s32_to_s16(struct comp_dev *dev, struct comp_buffer *sink, struct comp_buffer *source, uint32_t frames) { struct comp_data *cd = comp_get_drvdata(dev); - int32_t *src = (int32_t*) source->r_ptr; + int32_t i, *src = (int32_t*) source->r_ptr; int16_t *dest = (int16_t*) sink->w_ptr; - int i, j;
/* buffer sizes are always divisible by period frames */ - for (i = 0; i < frames; i++) { - for (j = 0; j < source->params.channels; j++) { - /* TODO: clamp when converting to int16_t */ - *dest = (int16_t)((*src * cd->volume[j]) >> 16); - dest++; - src++; - } + for (i = 0; i < frames * 2; i += 2) { + dest[i] = (((int32_t)src[i] >> 16) * cd->volume[0]) >> 16; + dest[i + 1] = (((int32_t)src[i + 1] >> 16) * cd->volume[1]) >> 16; }
- source->r_ptr = src; - sink->w_ptr = dest; + source->r_ptr = src + i; + sink->w_ptr = dest + i; }
/* copy and scale volume from 32 bit source buffer to 32 bit dest buffer */ @@ -131,20 +122,16 @@ static void vol_s32_to_s32(struct comp_dev *dev, struct comp_buffer *sink, { struct comp_data *cd = comp_get_drvdata(dev); int32_t *src = (int32_t*) source->r_ptr; - int32_t *dest = (int32_t*) sink->w_ptr; - int i, j; + int32_t i, *dest = (int32_t*) sink->w_ptr;
/* buffer sizes are always divisible by period frames */ - for (i = 0; i < frames; i++) { - for (j = 0; j < source->params.channels; j++) { - *dest = (*src * cd->volume[j]) >> 16; - dest++; - src++; - } + for (i = 0; i < frames * 2; i += 2) { + dest[i] = ((int64_t)src[i] * cd->volume[0]) >> 16; + dest[i + 1] = ((int64_t)src[i] * cd->volume[1]) >> 16; }
- source->r_ptr = src; - sink->w_ptr = dest; + source->r_ptr = src + i; + sink->w_ptr = dest + i; }
/* copy and scale volume from 16 bit source buffer to 16 bit dest buffer */ @@ -154,30 +141,64 @@ static void vol_s16_to_s16(struct comp_dev *dev, struct comp_buffer *sink, struct comp_data *cd = comp_get_drvdata(dev); int16_t *src = (int16_t*) source->r_ptr; int16_t *dest = (int16_t*) sink->w_ptr; - int i, j; + int32_t i;
/* buffer sizes are always divisible by period frames */ - for (i = 0; i < frames; i++) { - for (j = 0; j < source->params.channels; j++) { - int32_t val = (int32_t)*src; - /* TODO: clamp when converting to int16_t */ - *dest = (int16_t)((val * cd->volume[j]) >> 16); - - dest++; - src++; - } + for (i = 0; i < frames * 2; i += 2) { + dest[i] = ((int32_t)src[i] * cd->volume[0]) >> 16; + dest[i + 1] = ((int32_t)src[i + 1] * cd->volume[1]) >> 16; + } + + source->r_ptr = src + i; + sink->w_ptr = dest + i; +} + +/* copy and scale volume from 16 bit source buffer to 24 bit on 32 bit boundary dest buffer */ +static void vol_s16_to_s24(struct comp_dev *dev, struct comp_buffer *sink, + struct comp_buffer *source, uint32_t frames) +{ + struct comp_data *cd = comp_get_drvdata(dev); + int16_t *src = (int16_t*) source->r_ptr; + int32_t i, *dest = (int32_t*) sink->w_ptr; + + /* buffer sizes are always divisible by period frames */ + for (i = 0; i < frames * 2; i += 2) { + dest[i] = ((int32_t)src[i] * cd->volume[0]) >> 8; + dest[i + 1] = ((int32_t)src[i + 1] * cd->volume[0]) >> 8; }
- source->r_ptr = src; - sink->w_ptr = dest; + source->r_ptr = src + i; + sink->w_ptr = dest + i; +} + +/* copy and scale volume from 16 bit source buffer to 24 bit on 32 bit boundary dest buffer */ +static void vol_s24_to_s16(struct comp_dev *dev, struct comp_buffer *sink, + struct comp_buffer *source, uint32_t frames) +{ + struct comp_data *cd = comp_get_drvdata(dev); + int32_t i, *src = (int32_t*) source->r_ptr; + int16_t *dest = (int16_t*) sink->w_ptr; + + /* buffer sizes are always divisible by period frames */ + for (i = 0; i < frames * 2; i += 2) { + dest[i] = (int16_t)((((int32_t)src[i] >> 8) * + cd->volume[0]) >> 16); + dest[i + 1] = (int16_t)((((int32_t)src[i + 1] >> 8) * + cd->volume[0]) >> 16); + } + + source->r_ptr = src + i; + sink->w_ptr = dest + i; }
/* map of source and sink buffer formats to volume function */ static const struct comp_func_map func_map[] = { - {STREAM_FORMAT_S16_LE, STREAM_FORMAT_S16_LE, vol_s16_to_s16}, - {STREAM_FORMAT_S16_LE, STREAM_FORMAT_S32_LE, vol_s16_to_s32}, - {STREAM_FORMAT_S32_LE, STREAM_FORMAT_S16_LE, vol_s32_to_s16}, - {STREAM_FORMAT_S32_LE, STREAM_FORMAT_S32_LE, vol_s32_to_s32}, + {STREAM_FORMAT_S16_LE, STREAM_FORMAT_S16_LE, 2, vol_s16_to_s16}, + {STREAM_FORMAT_S16_LE, STREAM_FORMAT_S32_LE, 2, vol_s16_to_s32}, + {STREAM_FORMAT_S32_LE, STREAM_FORMAT_S16_LE, 2, vol_s32_to_s16}, + {STREAM_FORMAT_S32_LE, STREAM_FORMAT_S32_LE, 2, vol_s32_to_s32}, + {STREAM_FORMAT_S16_LE, STREAM_FORMAT_S24_3LE, 2, vol_s16_to_s24}, + {STREAM_FORMAT_S24_3LE, STREAM_FORMAT_S16_LE, 2, vol_s24_to_s16}, };
static void vol_update(struct comp_data *cd, uint32_t chan) @@ -421,6 +442,8 @@ static int volume_prepare(struct comp_dev *dev) continue; if (sink->params.pcm.format != func_map[i].sink) continue; + if (sink->params.channels != func_map[i].channels) + continue;
cd->scale_vol = func_map[i].func; goto found;
it is configured from host/codec side that using I2S mode, so switch it. --- src/ipc/intel-ipc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/ipc/intel-ipc.c b/src/ipc/intel-ipc.c index 1fdd73f..8d33830 100644 --- a/src/ipc/intel-ipc.c +++ b/src/ipc/intel-ipc.c @@ -561,7 +561,7 @@ static uint32_t ipc_device_set_formats(uint32_t header)
/* setup the DAI HW config - TODO hard coded due to IPC limitations */ dai_dev->dai_config.mclk = config_req.clock_frequency; - dai_dev->dai_config.format = DAI_FMT_DSP_B | DAI_FMT_CONT | + dai_dev->dai_config.format = DAI_FMT_I2S | DAI_FMT_CONT | DAI_FMT_NB_NF | DAI_FMT_CBS_CFS; dai_dev->dai_config.frame_size = 32; /* TODO 16bit stereo hard coded */ dai_dev->dai_config.bclk_fs = 32; /* 32 BCLKs per frame - */
On Thu, 2016-12-22 at 17:27 +0800, Keyon Jie wrote:
it is configured from host/codec side that using I2S mode, so switch it.
src/ipc/intel-ipc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/ipc/intel-ipc.c b/src/ipc/intel-ipc.c index 1fdd73f..8d33830 100644 --- a/src/ipc/intel-ipc.c +++ b/src/ipc/intel-ipc.c @@ -561,7 +561,7 @@ static uint32_t ipc_device_set_formats(uint32_t header)
/* setup the DAI HW config - TODO hard coded due to IPC limitations */ dai_dev->dai_config.mclk = config_req.clock_frequency;
- dai_dev->dai_config.format = DAI_FMT_DSP_B | DAI_FMT_CONT |
- dai_dev->dai_config.format = DAI_FMT_I2S | DAI_FMT_CONT | DAI_FMT_NB_NF | DAI_FMT_CBS_CFS; dai_dev->dai_config.frame_size = 32; /* TODO 16bit stereo hard coded */ dai_dev->dai_config.bclk_fs = 32; /* 32 BCLKs per frame - */
Ok, so this is to match the existing upstream machine drivers ? We do need to revisit this so it can be programmed at runtime.
Liam
-----Original Message----- From: Liam Girdwood [mailto:liam.r.girdwood@linux.intel.com] Sent: Thursday, December 22, 2016 7:21 PM To: Keyon Jie yang.jie@linux.intel.com Cc: sound-open-firmware@alsa-project.org; Zhang, Keqiao keqiao.zhang@intel.com; Jie, Yang yang.jie@intel.com; Ingalsuo, Seppo seppo.ingalsuo@intel.com; Lin, Mengdong mengdong.lin@intel.com Subject: Re: [Sound-open-firmware] [PATCH v2 4/7] ssp: switch dai format form PCM B mode to normal I2S mode
On Thu, 2016-12-22 at 17:27 +0800, Keyon Jie wrote:
it is configured from host/codec side that using I2S mode, so switch it.
src/ipc/intel-ipc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/ipc/intel-ipc.c b/src/ipc/intel-ipc.c index 1fdd73f..8d33830 100644 --- a/src/ipc/intel-ipc.c +++ b/src/ipc/intel-ipc.c @@ -561,7 +561,7 @@ static uint32_t ipc_device_set_formats(uint32_t header)
/* setup the DAI HW config - TODO hard coded due to IPC limitations */ dai_dev->dai_config.mclk = config_req.clock_frequency;
- dai_dev->dai_config.format = DAI_FMT_DSP_B | DAI_FMT_CONT |
- dai_dev->dai_config.format = DAI_FMT_I2S | DAI_FMT_CONT | DAI_FMT_NB_NF | DAI_FMT_CBS_CFS; dai_dev->dai_config.frame_size = 32; /* TODO 16bit stereo hard
coded */
dai_dev->dai_config.bclk_fs = 32; /* 32 BCLKs per frame - */
Ok, so this is to match the existing upstream machine drivers ? We do need to revisit this so it can be programmed at runtime.
Yes, and we already adding programmable in patch 5/7.
Thanks, ~Keyon
Liam
here change to get dai format setting from host via ipc, then we can align it with codec setting easily.
Signed-off-by: Keyon Jie yang.jie@linux.intel.com --- src/include/uapi/intel-ipc.h | 1 + src/ipc/intel-ipc.c | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/include/uapi/intel-ipc.h b/src/include/uapi/intel-ipc.h index a4b6d28..05992e5 100644 --- a/src/include/uapi/intel-ipc.h +++ b/src/include/uapi/intel-ipc.h @@ -514,6 +514,7 @@ struct ipc_intel_ipc_device_config_req { uint32_t ssp_interface; uint32_t clock_frequency; uint32_t mode; + uint32_t dai_fmt; uint16_t clock_divider; uint8_t channels; uint8_t reserved; diff --git a/src/ipc/intel-ipc.c b/src/ipc/intel-ipc.c index 8d33830..827c9f3 100644 --- a/src/ipc/intel-ipc.c +++ b/src/ipc/intel-ipc.c @@ -561,8 +561,7 @@ static uint32_t ipc_device_set_formats(uint32_t header)
/* setup the DAI HW config - TODO hard coded due to IPC limitations */ dai_dev->dai_config.mclk = config_req.clock_frequency; - dai_dev->dai_config.format = DAI_FMT_I2S | DAI_FMT_CONT | - DAI_FMT_NB_NF | DAI_FMT_CBS_CFS; + dai_dev->dai_config.format = config_req.dai_fmt; dai_dev->dai_config.frame_size = 32; /* TODO 16bit stereo hard coded */ dai_dev->dai_config.bclk_fs = 32; /* 32 BCLKs per frame - */ dai_dev->dai_config.mclk_fs = 256;
add stream_format to indicate the stream format that the dai buffer is using.
Signed-off-by: Keyon Jie yang.jie@linux.intel.com --- src/audio/dai.c | 9 +++++++++ src/platform/baytrail/include/platform/platform.h | 3 +++ 2 files changed, 12 insertions(+)
diff --git a/src/audio/dai.c b/src/audio/dai.c index afa1be1..51ff093 100644 --- a/src/audio/dai.c +++ b/src/audio/dai.c @@ -59,6 +59,7 @@ struct dai_data { struct dma_sg_config config;
int direction; + uint32_t stream_format; struct dai *ssp; struct dma *dma;
@@ -162,6 +163,8 @@ static struct comp_dev *dai_new_ssp(uint32_t type, uint32_t index, if (dd->chan < 0) goto error;
+ dd->stream_format = PLATFORM_SSP_STREAM_FORMAT; + /* set up callback */ //if (dd->ssp->plat_data.flags & DAI_FLAGS_IRQ_CB) dma_set_cb(dd->dma, dd->chan, DMA_IRQ_TYPE_LLIST, dai_dma_cb, dev); @@ -217,6 +220,9 @@ static int dai_playback_params(struct comp_dev *dev, dma_period_desc = &dma_buffer->desc.sink_period; dma_buffer->params = *params;
+ /* set it to dai stream format, for volume func correct mapping */ + dma_buffer->params.pcm.format = dd->stream_format; + if (list_is_empty(&config->elem_list)) { /* set up cyclic list of DMA elems */ for (i = 0; i < dma_period_desc->number; i++) { @@ -275,6 +281,9 @@ static int dai_capture_params(struct comp_dev *dev, dma_period_desc = &dma_buffer->desc.source_period; dma_buffer->params = *params;
+ /* set it to dai stream format, for volume func correct mapping */ + dma_buffer->params.pcm.format = dd->stream_format; + if (list_is_empty(&config->elem_list)) { /* set up cyclic list of DMA elems */ for (i = 0; i < dma_period_desc->number; i++) { diff --git a/src/platform/baytrail/include/platform/platform.h b/src/platform/baytrail/include/platform/platform.h index bbf16d5..e8395a4 100644 --- a/src/platform/baytrail/include/platform/platform.h +++ b/src/platform/baytrail/include/platform/platform.h @@ -38,6 +38,9 @@ /* default static pipeline SSP port - not used for dynamic pipes */ #define PLATFORM_SSP_PORT 2
+/* default SSP stream format - need aligned with codec setting*/ +#define PLATFORM_SSP_STREAM_FORMAT STREAM_FORMAT_S16_LE + /* IPC Interrupt */ #define PLATFORM_IPC_INTERUPT IRQ_NUM_EXT_IA
On Thu, 2016-12-22 at 17:28 +0800, Keyon Jie wrote:
add stream_format to indicate the stream format that the dai buffer is using.
Signed-off-by: Keyon Jie yang.jie@linux.intel.com
src/audio/dai.c | 9 +++++++++ src/platform/baytrail/include/platform/platform.h | 3 +++ 2 files changed, 12 insertions(+)
diff --git a/src/audio/dai.c b/src/audio/dai.c index afa1be1..51ff093 100644 --- a/src/audio/dai.c +++ b/src/audio/dai.c @@ -59,6 +59,7 @@ struct dai_data { struct dma_sg_config config;
int direction;
- uint32_t stream_format; struct dai *ssp; struct dma *dma;
@@ -162,6 +163,8 @@ static struct comp_dev *dai_new_ssp(uint32_t type, uint32_t index, if (dd->chan < 0) goto error;
- dd->stream_format = PLATFORM_SSP_STREAM_FORMAT;
- /* set up callback */ //if (dd->ssp->plat_data.flags & DAI_FLAGS_IRQ_CB) dma_set_cb(dd->dma, dd->chan, DMA_IRQ_TYPE_LLIST, dai_dma_cb, dev);
@@ -217,6 +220,9 @@ static int dai_playback_params(struct comp_dev *dev, dma_period_desc = &dma_buffer->desc.sink_period; dma_buffer->params = *params;
- /* set it to dai stream format, for volume func correct mapping */
- dma_buffer->params.pcm.format = dd->stream_format;
- if (list_is_empty(&config->elem_list)) { /* set up cyclic list of DMA elems */ for (i = 0; i < dma_period_desc->number; i++) {
@@ -275,6 +281,9 @@ static int dai_capture_params(struct comp_dev *dev, dma_period_desc = &dma_buffer->desc.source_period; dma_buffer->params = *params;
- /* set it to dai stream format, for volume func correct mapping */
- dma_buffer->params.pcm.format = dd->stream_format;
- if (list_is_empty(&config->elem_list)) { /* set up cyclic list of DMA elems */ for (i = 0; i < dma_period_desc->number; i++) {
diff --git a/src/platform/baytrail/include/platform/platform.h b/src/platform/baytrail/include/platform/platform.h index bbf16d5..e8395a4 100644 --- a/src/platform/baytrail/include/platform/platform.h +++ b/src/platform/baytrail/include/platform/platform.h @@ -38,6 +38,9 @@ /* default static pipeline SSP port - not used for dynamic pipes */ #define PLATFORM_SSP_PORT 2
+/* default SSP stream format - need aligned with codec setting*/ +#define PLATFORM_SSP_STREAM_FORMAT STREAM_FORMAT_S16_LE
24 bit ?
Again, we will revisit this once our IPC can pass this info.
/* IPC Interrupt */ #define PLATFORM_IPC_INTERUPT IRQ_NUM_EXT_IA
-----Original Message----- From: Liam Girdwood [mailto:liam.r.girdwood@linux.intel.com] Sent: Thursday, December 22, 2016 7:31 PM To: Keyon Jie yang.jie@linux.intel.com Cc: sound-open-firmware@alsa-project.org; Zhang, Keqiao keqiao.zhang@intel.com; Jie, Yang yang.jie@intel.com; Ingalsuo, Seppo seppo.ingalsuo@intel.com; Lin, Mengdong mengdong.lin@intel.com Subject: Re: [Sound-open-firmware] [PATCH v2 6/7] dai: add stream_format to dai_data for codec stream
On Thu, 2016-12-22 at 17:28 +0800, Keyon Jie wrote:
add stream_format to indicate the stream format that the dai buffer is using.
Signed-off-by: Keyon Jie yang.jie@linux.intel.com
src/audio/dai.c | 9 +++++++++ src/platform/baytrail/include/platform/platform.h | 3 +++ 2 files changed, 12 insertions(+)
diff --git a/src/audio/dai.c b/src/audio/dai.c index afa1be1..51ff093 100644 --- a/src/audio/dai.c +++ b/src/audio/dai.c @@ -59,6 +59,7 @@ struct dai_data { struct dma_sg_config config;
int direction;
- uint32_t stream_format; struct dai *ssp; struct dma *dma;
@@ -162,6 +163,8 @@ static struct comp_dev *dai_new_ssp(uint32_t type,
uint32_t index,
if (dd->chan < 0) goto error;
- dd->stream_format = PLATFORM_SSP_STREAM_FORMAT;
- /* set up callback */ //if (dd->ssp->plat_data.flags & DAI_FLAGS_IRQ_CB) dma_set_cb(dd->dma, dd->chan, DMA_IRQ_TYPE_LLIST,
dai_dma_cb, dev);
@@ -217,6 +220,9 @@ static int dai_playback_params(struct comp_dev *dev, dma_period_desc = &dma_buffer->desc.sink_period; dma_buffer->params = *params;
- /* set it to dai stream format, for volume func correct mapping */
- dma_buffer->params.pcm.format = dd->stream_format;
- if (list_is_empty(&config->elem_list)) { /* set up cyclic list of DMA elems */ for (i = 0; i < dma_period_desc->number; i++) { @@ -275,6
+281,9 @@
static int dai_capture_params(struct comp_dev *dev, dma_period_desc = &dma_buffer->desc.source_period; dma_buffer->params = *params;
- /* set it to dai stream format, for volume func correct mapping */
- dma_buffer->params.pcm.format = dd->stream_format;
- if (list_is_empty(&config->elem_list)) { /* set up cyclic list of DMA elems */ for (i = 0; i < dma_period_desc->number; i++) { diff --git
a/src/platform/baytrail/include/platform/platform.h b/src/platform/baytrail/include/platform/platform.h index bbf16d5..e8395a4 100644 --- a/src/platform/baytrail/include/platform/platform.h +++ b/src/platform/baytrail/include/platform/platform.h @@ -38,6 +38,9 @@ /* default static pipeline SSP port - not used for dynamic pipes */ #define PLATFORM_SSP_PORT 2
+/* default SSP stream format - need aligned with codec setting*/ +#define PLATFORM_SSP_STREAM_FORMAT STREAM_FORMAT_S16_LE
24 bit ?
Again, we will revisit this once our IPC can pass this info.
This is only for compatibility. It will be changed to S24_3LE in patch 7/7.
Thanks, ~Keyon
/* IPC Interrupt */ #define PLATFORM_IPC_INTERUPT IRQ_NUM_EXT_IA
change to get ssp stream format from host via ipc, which make it configurable and easy aligned with codec settings.
set the default format to s24_3le.
Signed-off-by: Keyon Jie yang.jie@linux.intel.com --- src/audio/dai.c | 1 + src/include/reef/dai.h | 1 + src/include/reef/stream.h | 20 ++++++++++++++++++++ src/include/uapi/intel-ipc.h | 1 + src/ipc/intel-ipc.c | 21 +++++++++++++++++---- src/platform/baytrail/include/platform/platform.h | 4 ++-- 6 files changed, 42 insertions(+), 6 deletions(-)
diff --git a/src/audio/dai.c b/src/audio/dai.c index 51ff093..f185569 100644 --- a/src/audio/dai.c +++ b/src/audio/dai.c @@ -451,6 +451,7 @@ static int dai_config(struct comp_dev *dev, struct dai_config *dai_config) { struct dai_data *dd = comp_get_drvdata(dev);
+ dd->stream_format = dai_config->stream_format; return dai_set_config(dd->ssp, dai_config); }
diff --git a/src/include/reef/dai.h b/src/include/reef/dai.h index 5a29e85..095be4c 100644 --- a/src/include/reef/dai.h +++ b/src/include/reef/dai.h @@ -100,6 +100,7 @@ struct dai_slot_map { /* DAI runtime hardware configuration */ struct dai_config { uint32_t format; + uint32_t stream_format; uint32_t frame_size; /* in BCLKs */ struct dai_slot_map tx_slot_map[DAI_NUM_SLOT_MAPS]; struct dai_slot_map rx_slot_map[DAI_NUM_SLOT_MAPS]; diff --git a/src/include/reef/stream.h b/src/include/reef/stream.h index f6101f5..7da7891 100644 --- a/src/include/reef/stream.h +++ b/src/include/reef/stream.h @@ -40,6 +40,26 @@ #define STREAM_TYPE_VORBIS 1 /* other compressed stream types here if supported */
+/* pcm format from host side */ +#define SNDRV_PCM_FORMAT_S8 0 +#define SNDRV_PCM_FORMAT_U8 1 +#define SNDRV_PCM_FORMAT_S16_LE 2 +#define SNDRV_PCM_FORMAT_S16_BE 3 +#define SNDRV_PCM_FORMAT_U16_LE 4 +#define SNDRV_PCM_FORMAT_U16_BE 5 +#define SNDRV_PCM_FORMAT_S24_LE 6 /* low three bytes */ +#define SNDRV_PCM_FORMAT_S24_BE 7 /* low three bytes */ +#define SNDRV_PCM_FORMAT_U24_LE 8 /* low three bytes */ +#define SNDRV_PCM_FORMAT_U24_BE 9 /* low three bytes */ +#define SNDRV_PCM_FORMAT_S32_LE 10 +#define SNDRV_PCM_FORMAT_S32_BE 11 +#define SNDRV_PCM_FORMAT_U32_LE 12 +#define SNDRV_PCM_FORMAT_U32_BE 13 +#define SNDRV_PCM_FORMAT_S24_3LE 32 /* in three bytes */ +#define SNDRV_PCM_FORMAT_S24_3BE 33 /* in three bytes */ +#define SNDRV_PCM_FORMAT_U24_3LE 34 /* in three bytes */ +#define SNDRV_PCM_FORMAT_U24_3BE 35 /* in three bytes */ + /* supported format masks */ #define STREAM_FORMAT_S16_LE 1 #define STREAM_FORMAT_S24_3LE 2 diff --git a/src/include/uapi/intel-ipc.h b/src/include/uapi/intel-ipc.h index 05992e5..c6d3ae8 100644 --- a/src/include/uapi/intel-ipc.h +++ b/src/include/uapi/intel-ipc.h @@ -515,6 +515,7 @@ struct ipc_intel_ipc_device_config_req { uint32_t clock_frequency; uint32_t mode; uint32_t dai_fmt; + uint32_t dai_stream_format; uint16_t clock_divider; uint8_t channels; uint8_t reserved; diff --git a/src/ipc/intel-ipc.c b/src/ipc/intel-ipc.c index 827c9f3..b959baa 100644 --- a/src/ipc/intel-ipc.c +++ b/src/ipc/intel-ipc.c @@ -559,12 +559,25 @@ static uint32_t ipc_device_set_formats(uint32_t header) goto error; }
- /* setup the DAI HW config - TODO hard coded due to IPC limitations */ dai_dev->dai_config.mclk = config_req.clock_frequency; dai_dev->dai_config.format = config_req.dai_fmt; - dai_dev->dai_config.frame_size = 32; /* TODO 16bit stereo hard coded */ - dai_dev->dai_config.bclk_fs = 32; /* 32 BCLKs per frame - */ - dai_dev->dai_config.mclk_fs = 256; + + switch (config_req.dai_stream_format) { + case SNDRV_PCM_FORMAT_S24_3LE: + dai_dev->dai_config.stream_format = STREAM_FORMAT_S24_3LE; + dai_dev->dai_config.frame_size = 24; + dai_dev->dai_config.bclk_fs = 50; /* 50 BCLKs per frame - */ + dai_dev->dai_config.mclk_fs = 400; + break; + case SNDRV_PCM_FORMAT_S16_LE: + dai_dev->dai_config.stream_format = STREAM_FORMAT_S16_LE; + dai_dev->dai_config.frame_size = 16; + dai_dev->dai_config.bclk_fs = 32; /* 50 BCLKs per frame - */ + dai_dev->dai_config.mclk_fs = 256; + break; + default: + goto error; + } dai_dev->dai_config.clk_src = SSP_CLK_EXT;
comp_dai_config(dai_dev->dev.cd, &dai_dev->dai_config); diff --git a/src/platform/baytrail/include/platform/platform.h b/src/platform/baytrail/include/platform/platform.h index e8395a4..7af3b36 100644 --- a/src/platform/baytrail/include/platform/platform.h +++ b/src/platform/baytrail/include/platform/platform.h @@ -39,7 +39,7 @@ #define PLATFORM_SSP_PORT 2
/* default SSP stream format - need aligned with codec setting*/ -#define PLATFORM_SSP_STREAM_FORMAT STREAM_FORMAT_S16_LE +#define PLATFORM_SSP_STREAM_FORMAT STREAM_FORMAT_S24_3LE
/* IPC Interrupt */ #define PLATFORM_IPC_INTERUPT IRQ_NUM_EXT_IA @@ -62,7 +62,7 @@ #define PLAT_HOST_PERIODS 2 /* give enough latency for DMA refill */
/* Platform Dev DMA buffer config - these should align with DMA engine */ -#define PLAT_DEV_PERSIZE 256 /* must be multiple of DMA+DEV burst size */ +#define PLAT_DEV_PERSIZE 512 /* must be multiple of DMA+DEV burst size */ #define PLAT_DEV_PERIODS 2 /* give enough latency for DMA refill */
/* DMA channel drain timeout in microseconds */
On Thu, 2016-12-22 at 17:28 +0800, Keyon Jie wrote:
change to get ssp stream format from host via ipc, which make it configurable and easy aligned with codec settings.
set the default format to s24_3le.
This format is for DAI only, it makes more sense to use some ints to specify number of bits i.e
phy_chan_size = 25; // size of physical channel on DAI # BCLKs log_chan_size = 24; // number of valid PCM data bits for that channel
Lets revisit this when we do IPC.
Liam
Signed-off-by: Keyon Jie yang.jie@linux.intel.com
src/audio/dai.c | 1 + src/include/reef/dai.h | 1 + src/include/reef/stream.h | 20 ++++++++++++++++++++ src/include/uapi/intel-ipc.h | 1 + src/ipc/intel-ipc.c | 21 +++++++++++++++++---- src/platform/baytrail/include/platform/platform.h | 4 ++-- 6 files changed, 42 insertions(+), 6 deletions(-)
diff --git a/src/audio/dai.c b/src/audio/dai.c index 51ff093..f185569 100644 --- a/src/audio/dai.c +++ b/src/audio/dai.c @@ -451,6 +451,7 @@ static int dai_config(struct comp_dev *dev, struct dai_config *dai_config) { struct dai_data *dd = comp_get_drvdata(dev);
- dd->stream_format = dai_config->stream_format; return dai_set_config(dd->ssp, dai_config);
}
diff --git a/src/include/reef/dai.h b/src/include/reef/dai.h index 5a29e85..095be4c 100644 --- a/src/include/reef/dai.h +++ b/src/include/reef/dai.h @@ -100,6 +100,7 @@ struct dai_slot_map { /* DAI runtime hardware configuration */ struct dai_config { uint32_t format;
- uint32_t stream_format; uint32_t frame_size; /* in BCLKs */ struct dai_slot_map tx_slot_map[DAI_NUM_SLOT_MAPS]; struct dai_slot_map rx_slot_map[DAI_NUM_SLOT_MAPS];
diff --git a/src/include/reef/stream.h b/src/include/reef/stream.h index f6101f5..7da7891 100644 --- a/src/include/reef/stream.h +++ b/src/include/reef/stream.h @@ -40,6 +40,26 @@ #define STREAM_TYPE_VORBIS 1 /* other compressed stream types here if supported */
+/* pcm format from host side */ +#define SNDRV_PCM_FORMAT_S8 0 +#define SNDRV_PCM_FORMAT_U8 1 +#define SNDRV_PCM_FORMAT_S16_LE 2 +#define SNDRV_PCM_FORMAT_S16_BE 3 +#define SNDRV_PCM_FORMAT_U16_LE 4 +#define SNDRV_PCM_FORMAT_U16_BE 5 +#define SNDRV_PCM_FORMAT_S24_LE 6 /* low three bytes */ +#define SNDRV_PCM_FORMAT_S24_BE 7 /* low three bytes */ +#define SNDRV_PCM_FORMAT_U24_LE 8 /* low three bytes */ +#define SNDRV_PCM_FORMAT_U24_BE 9 /* low three bytes */ +#define SNDRV_PCM_FORMAT_S32_LE 10 +#define SNDRV_PCM_FORMAT_S32_BE 11 +#define SNDRV_PCM_FORMAT_U32_LE 12 +#define SNDRV_PCM_FORMAT_U32_BE 13 +#define SNDRV_PCM_FORMAT_S24_3LE 32 /* in three bytes */ +#define SNDRV_PCM_FORMAT_S24_3BE 33 /* in three bytes */ +#define SNDRV_PCM_FORMAT_U24_3LE 34 /* in three bytes */ +#define SNDRV_PCM_FORMAT_U24_3BE 35 /* in three bytes */
/* supported format masks */ #define STREAM_FORMAT_S16_LE 1 #define STREAM_FORMAT_S24_3LE 2 diff --git a/src/include/uapi/intel-ipc.h b/src/include/uapi/intel-ipc.h index 05992e5..c6d3ae8 100644 --- a/src/include/uapi/intel-ipc.h +++ b/src/include/uapi/intel-ipc.h @@ -515,6 +515,7 @@ struct ipc_intel_ipc_device_config_req { uint32_t clock_frequency; uint32_t mode; uint32_t dai_fmt;
- uint32_t dai_stream_format; uint16_t clock_divider; uint8_t channels; uint8_t reserved;
diff --git a/src/ipc/intel-ipc.c b/src/ipc/intel-ipc.c index 827c9f3..b959baa 100644 --- a/src/ipc/intel-ipc.c +++ b/src/ipc/intel-ipc.c @@ -559,12 +559,25 @@ static uint32_t ipc_device_set_formats(uint32_t header) goto error; }
- /* setup the DAI HW config - TODO hard coded due to IPC limitations */ dai_dev->dai_config.mclk = config_req.clock_frequency; dai_dev->dai_config.format = config_req.dai_fmt;
- dai_dev->dai_config.frame_size = 32; /* TODO 16bit stereo hard coded */
- dai_dev->dai_config.bclk_fs = 32; /* 32 BCLKs per frame - */
- dai_dev->dai_config.mclk_fs = 256;
switch (config_req.dai_stream_format) {
case SNDRV_PCM_FORMAT_S24_3LE:
dai_dev->dai_config.stream_format = STREAM_FORMAT_S24_3LE;
dai_dev->dai_config.frame_size = 24;
dai_dev->dai_config.bclk_fs = 50; /* 50 BCLKs per frame - */
dai_dev->dai_config.mclk_fs = 400;
break;
case SNDRV_PCM_FORMAT_S16_LE:
dai_dev->dai_config.stream_format = STREAM_FORMAT_S16_LE;
dai_dev->dai_config.frame_size = 16;
dai_dev->dai_config.bclk_fs = 32; /* 50 BCLKs per frame - */
dai_dev->dai_config.mclk_fs = 256;
break;
default:
goto error;
} dai_dev->dai_config.clk_src = SSP_CLK_EXT;
comp_dai_config(dai_dev->dev.cd, &dai_dev->dai_config);
diff --git a/src/platform/baytrail/include/platform/platform.h b/src/platform/baytrail/include/platform/platform.h index e8395a4..7af3b36 100644 --- a/src/platform/baytrail/include/platform/platform.h +++ b/src/platform/baytrail/include/platform/platform.h @@ -39,7 +39,7 @@ #define PLATFORM_SSP_PORT 2
/* default SSP stream format - need aligned with codec setting*/ -#define PLATFORM_SSP_STREAM_FORMAT STREAM_FORMAT_S16_LE +#define PLATFORM_SSP_STREAM_FORMAT STREAM_FORMAT_S24_3LE
/* IPC Interrupt */ #define PLATFORM_IPC_INTERUPT IRQ_NUM_EXT_IA @@ -62,7 +62,7 @@ #define PLAT_HOST_PERIODS 2 /* give enough latency for DMA refill */
/* Platform Dev DMA buffer config - these should align with DMA engine */ -#define PLAT_DEV_PERSIZE 256 /* must be multiple of DMA+DEV burst size */ +#define PLAT_DEV_PERSIZE 512 /* must be multiple of DMA+DEV burst size */ #define PLAT_DEV_PERIODS 2 /* give enough latency for DMA refill */
/* DMA channel drain timeout in microseconds */
-----Original Message----- From: Liam Girdwood [mailto:liam.r.girdwood@linux.intel.com] Sent: Thursday, December 22, 2016 7:43 PM To: Keyon Jie yang.jie@linux.intel.com Cc: sound-open-firmware@alsa-project.org; Zhang, Keqiao keqiao.zhang@intel.com; Jie, Yang yang.jie@intel.com; Ingalsuo, Seppo seppo.ingalsuo@intel.com; Lin, Mengdong mengdong.lin@intel.com Subject: Re: [Sound-open-firmware] [PATCH v2 7/7] intel-ipc: change to get ssp stream format from ipc
On Thu, 2016-12-22 at 17:28 +0800, Keyon Jie wrote:
change to get ssp stream format from host via ipc, which make it configurable and easy aligned with codec settings.
set the default format to s24_3le.
This format is for DAI only, it makes more sense to use some ints to specify number of bits i.e
phy_chan_size = 25; // size of physical channel on DAI # BCLKs log_chan_size = 24; // number of valid PCM data bits for that channel
Lets revisit this when we do IPC.
Yes, we need to revisit it and work out a better solution in future, e.g. during enabling TDM...
Thanks, ~Keyon
Liam
Signed-off-by: Keyon Jie yang.jie@linux.intel.com
src/audio/dai.c | 1 + src/include/reef/dai.h | 1 + src/include/reef/stream.h | 20 ++++++++++++++++++++ src/include/uapi/intel-ipc.h | 1 + src/ipc/intel-ipc.c | 21 +++++++++++++++++---- src/platform/baytrail/include/platform/platform.h | 4 ++-- 6 files changed, 42 insertions(+), 6 deletions(-)
diff --git a/src/audio/dai.c b/src/audio/dai.c index 51ff093..f185569 100644 --- a/src/audio/dai.c +++ b/src/audio/dai.c @@ -451,6 +451,7 @@ static int dai_config(struct comp_dev *dev, struct dai_config *dai_config) { struct dai_data *dd = comp_get_drvdata(dev);
- dd->stream_format = dai_config->stream_format; return dai_set_config(dd->ssp, dai_config); }
diff --git a/src/include/reef/dai.h b/src/include/reef/dai.h index 5a29e85..095be4c 100644 --- a/src/include/reef/dai.h +++ b/src/include/reef/dai.h @@ -100,6 +100,7 @@ struct dai_slot_map { /* DAI runtime hardware configuration */ struct dai_config { uint32_t format;
- uint32_t stream_format; uint32_t frame_size; /* in BCLKs */ struct dai_slot_map tx_slot_map[DAI_NUM_SLOT_MAPS]; struct dai_slot_map rx_slot_map[DAI_NUM_SLOT_MAPS]; diff --git
a/src/include/reef/stream.h b/src/include/reef/stream.h index f6101f5..7da7891 100644 --- a/src/include/reef/stream.h +++ b/src/include/reef/stream.h @@ -40,6 +40,26 @@ #define STREAM_TYPE_VORBIS 1 /* other compressed stream types here if supported */
+/* pcm format from host side */ +#define SNDRV_PCM_FORMAT_S8 0 +#define SNDRV_PCM_FORMAT_U8 1 +#define SNDRV_PCM_FORMAT_S16_LE 2 +#define SNDRV_PCM_FORMAT_S16_BE 3 +#define SNDRV_PCM_FORMAT_U16_LE 4 +#define SNDRV_PCM_FORMAT_U16_BE 5 +#define SNDRV_PCM_FORMAT_S24_LE 6 /* low three bytes */ +#define SNDRV_PCM_FORMAT_S24_BE 7 /* low three bytes */ +#define SNDRV_PCM_FORMAT_U24_LE 8 /* low three bytes */ +#define SNDRV_PCM_FORMAT_U24_BE 9 /* low three bytes */ +#define SNDRV_PCM_FORMAT_S32_LE 10 +#define SNDRV_PCM_FORMAT_S32_BE 11 +#define SNDRV_PCM_FORMAT_U32_LE 12 +#define SNDRV_PCM_FORMAT_U32_BE 13 +#define SNDRV_PCM_FORMAT_S24_3LE 32 /* in three bytes */ +#define SNDRV_PCM_FORMAT_S24_3BE 33 /* in three
bytes */
+#define SNDRV_PCM_FORMAT_U24_3LE 34 /* in three
bytes */
+#define SNDRV_PCM_FORMAT_U24_3BE 35 /* in three
bytes */
/* supported format masks */ #define STREAM_FORMAT_S16_LE 1 #define STREAM_FORMAT_S24_3LE 2 diff --git a/src/include/uapi/intel-ipc.h b/src/include/uapi/intel-ipc.h index 05992e5..c6d3ae8 100644 --- a/src/include/uapi/intel-ipc.h +++ b/src/include/uapi/intel-ipc.h @@ -515,6 +515,7 @@ struct ipc_intel_ipc_device_config_req { uint32_t clock_frequency; uint32_t mode; uint32_t dai_fmt;
- uint32_t dai_stream_format; uint16_t clock_divider; uint8_t channels; uint8_t reserved;
diff --git a/src/ipc/intel-ipc.c b/src/ipc/intel-ipc.c index 827c9f3..b959baa 100644 --- a/src/ipc/intel-ipc.c +++ b/src/ipc/intel-ipc.c @@ -559,12 +559,25 @@ static uint32_t ipc_device_set_formats(uint32_t
header)
goto error;
}
- /* setup the DAI HW config - TODO hard coded due to IPC limitations */ dai_dev->dai_config.mclk = config_req.clock_frequency; dai_dev->dai_config.format = config_req.dai_fmt;
- dai_dev->dai_config.frame_size = 32; /* TODO 16bit stereo hard
coded */
- dai_dev->dai_config.bclk_fs = 32; /* 32 BCLKs per frame - */
- dai_dev->dai_config.mclk_fs = 256;
- switch (config_req.dai_stream_format) {
- case SNDRV_PCM_FORMAT_S24_3LE:
dai_dev->dai_config.stream_format =
STREAM_FORMAT_S24_3LE;
dai_dev->dai_config.frame_size = 24;
dai_dev->dai_config.bclk_fs = 50; /* 50 BCLKs per frame
- */
dai_dev->dai_config.mclk_fs = 400;
break;
- case SNDRV_PCM_FORMAT_S16_LE:
dai_dev->dai_config.stream_format =
STREAM_FORMAT_S16_LE;
dai_dev->dai_config.frame_size = 16;
dai_dev->dai_config.bclk_fs = 32; /* 50 BCLKs per frame
- */
dai_dev->dai_config.mclk_fs = 256;
break;
default:
goto error;
} dai_dev->dai_config.clk_src = SSP_CLK_EXT;
comp_dai_config(dai_dev->dev.cd, &dai_dev->dai_config); diff --git
a/src/platform/baytrail/include/platform/platform.h b/src/platform/baytrail/include/platform/platform.h index e8395a4..7af3b36 100644 --- a/src/platform/baytrail/include/platform/platform.h +++ b/src/platform/baytrail/include/platform/platform.h @@ -39,7 +39,7 @@ #define PLATFORM_SSP_PORT 2
/* default SSP stream format - need aligned with codec setting*/ -#define PLATFORM_SSP_STREAM_FORMAT STREAM_FORMAT_S16_LE +#define PLATFORM_SSP_STREAM_FORMAT STREAM_FORMAT_S24_3LE
/* IPC Interrupt */ #define PLATFORM_IPC_INTERUPT IRQ_NUM_EXT_IA @@ -62,7 +62,7 @@ #define PLAT_HOST_PERIODS 2 /* give enough latency for DMA refill
*/
/* Platform Dev DMA buffer config - these should align with DMA engine */ -#define PLAT_DEV_PERSIZE 256 /* must be multiple of DMA+DEV burst
size */
+#define PLAT_DEV_PERSIZE 512 /* must be multiple of DMA+DEV burst
size */
#define PLAT_DEV_PERIODS 2 /* give enough latency for DMA refill
*/
/* DMA channel drain timeout in microseconds */
-----Original Message----- From: Jie, Yang Sent: Thursday, December 22, 2016 10:17 PM To: Liam Girdwood liam.r.girdwood@linux.intel.com; Keyon Jie yang.jie@linux.intel.com Cc: sound-open-firmware@alsa-project.org; Zhang, Keqiao keqiao.zhang@intel.com; Ingalsuo, Seppo seppo.ingalsuo@intel.com; Lin, Mengdong mengdong.lin@intel.com Subject: RE: [Sound-open-firmware] [PATCH v2 7/7] intel-ipc: change to get ssp stream format from ipc
-----Original Message----- From: Liam Girdwood [mailto:liam.r.girdwood@linux.intel.com] Sent: Thursday, December 22, 2016 7:43 PM To: Keyon Jie yang.jie@linux.intel.com Cc: sound-open-firmware@alsa-project.org; Zhang, Keqiao keqiao.zhang@intel.com; Jie, Yang yang.jie@intel.com; Ingalsuo, Seppo seppo.ingalsuo@intel.com; Lin, Mengdong mengdong.lin@intel.com Subject: Re: [Sound-open-firmware] [PATCH v2 7/7] intel-ipc: change to get ssp stream format from ipc
On Thu, 2016-12-22 at 17:28 +0800, Keyon Jie wrote:
change to get ssp stream format from host via ipc, which make it configurable and easy aligned with codec settings.
set the default format to s24_3le.
This format is for DAI only, it makes more sense to use some ints to specify number of bits i.e
I also considered this, e.g. using bitdepth, but give up at the end, I thought passing this exactly same requirement as what we pass to codec (SNDRV_PCM_FORMAT_S24_3LE), and let codec/adsp dai decide what detail Format/registers setting they should do. This looks more extendable for future?
Thanks, ~Keyon
phy_chan_size = 25; // size of physical channel on DAI # BCLKs log_chan_size = 24; // number of valid PCM data bits for that channel
Lets revisit this when we do IPC.
Yes, we need to revisit it and work out a better solution in future, e.g. during enabling TDM...
Thanks, ~Keyon
Liam
Signed-off-by: Keyon Jie yang.jie@linux.intel.com
src/audio/dai.c | 1 + src/include/reef/dai.h | 1 + src/include/reef/stream.h | 20 ++++++++++++++++++++ src/include/uapi/intel-ipc.h | 1 + src/ipc/intel-ipc.c | 21 +++++++++++++++++---- src/platform/baytrail/include/platform/platform.h | 4 ++-- 6 files changed, 42 insertions(+), 6 deletions(-)
diff --git a/src/audio/dai.c b/src/audio/dai.c index 51ff093..f185569 100644 --- a/src/audio/dai.c +++ b/src/audio/dai.c @@ -451,6 +451,7 @@ static int dai_config(struct comp_dev *dev, struct dai_config *dai_config) { struct dai_data *dd = comp_get_drvdata(dev);
- dd->stream_format = dai_config->stream_format; return dai_set_config(dd->ssp, dai_config); }
diff --git a/src/include/reef/dai.h b/src/include/reef/dai.h index 5a29e85..095be4c 100644 --- a/src/include/reef/dai.h +++ b/src/include/reef/dai.h @@ -100,6 +100,7 @@ struct dai_slot_map { /* DAI runtime hardware configuration */ struct dai_config { uint32_t format;
- uint32_t stream_format; uint32_t frame_size; /* in BCLKs */ struct dai_slot_map tx_slot_map[DAI_NUM_SLOT_MAPS]; struct dai_slot_map rx_slot_map[DAI_NUM_SLOT_MAPS]; diff --git
a/src/include/reef/stream.h b/src/include/reef/stream.h index f6101f5..7da7891 100644 --- a/src/include/reef/stream.h +++ b/src/include/reef/stream.h @@ -40,6 +40,26 @@ #define STREAM_TYPE_VORBIS 1 /* other compressed stream types here if supported */
+/* pcm format from host side */ +#define SNDRV_PCM_FORMAT_S8 0 +#define SNDRV_PCM_FORMAT_U8 1 +#define SNDRV_PCM_FORMAT_S16_LE 2 +#define SNDRV_PCM_FORMAT_S16_BE 3 +#define SNDRV_PCM_FORMAT_U16_LE 4 +#define SNDRV_PCM_FORMAT_U16_BE 5 +#define SNDRV_PCM_FORMAT_S24_LE 6 /* low three bytes */ +#define SNDRV_PCM_FORMAT_S24_BE 7 /* low three bytes */ +#define SNDRV_PCM_FORMAT_U24_LE 8 /* low three bytes */ +#define SNDRV_PCM_FORMAT_U24_BE 9 /* low three bytes */ +#define SNDRV_PCM_FORMAT_S32_LE 10 +#define SNDRV_PCM_FORMAT_S32_BE 11 +#define SNDRV_PCM_FORMAT_U32_LE 12 +#define SNDRV_PCM_FORMAT_U32_BE 13 +#define SNDRV_PCM_FORMAT_S24_3LE 32 /* in three bytes */ +#define SNDRV_PCM_FORMAT_S24_3BE 33 /* in three
bytes */
+#define SNDRV_PCM_FORMAT_U24_3LE 34 /* in three
bytes */
+#define SNDRV_PCM_FORMAT_U24_3BE 35 /* in three
bytes */
/* supported format masks */ #define STREAM_FORMAT_S16_LE 1 #define STREAM_FORMAT_S24_3LE 2 diff --git a/src/include/uapi/intel-ipc.h b/src/include/uapi/intel-ipc.h index 05992e5..c6d3ae8 100644 --- a/src/include/uapi/intel-ipc.h +++ b/src/include/uapi/intel-ipc.h @@ -515,6 +515,7 @@ struct ipc_intel_ipc_device_config_req { uint32_t clock_frequency; uint32_t mode; uint32_t dai_fmt;
- uint32_t dai_stream_format; uint16_t clock_divider; uint8_t channels; uint8_t reserved;
diff --git a/src/ipc/intel-ipc.c b/src/ipc/intel-ipc.c index 827c9f3..b959baa 100644 --- a/src/ipc/intel-ipc.c +++ b/src/ipc/intel-ipc.c @@ -559,12 +559,25 @@ static uint32_t ipc_device_set_formats(uint32_t
header)
goto error;
}
- /* setup the DAI HW config - TODO hard coded due to IPC limitations */ dai_dev->dai_config.mclk = config_req.clock_frequency; dai_dev->dai_config.format = config_req.dai_fmt;
- dai_dev->dai_config.frame_size = 32; /* TODO 16bit stereo hard
coded */
- dai_dev->dai_config.bclk_fs = 32; /* 32 BCLKs per frame - */
- dai_dev->dai_config.mclk_fs = 256;
- switch (config_req.dai_stream_format) {
- case SNDRV_PCM_FORMAT_S24_3LE:
dai_dev->dai_config.stream_format =
STREAM_FORMAT_S24_3LE;
dai_dev->dai_config.frame_size = 24;
dai_dev->dai_config.bclk_fs = 50; /* 50 BCLKs per frame
- */
dai_dev->dai_config.mclk_fs = 400;
break;
- case SNDRV_PCM_FORMAT_S16_LE:
dai_dev->dai_config.stream_format =
STREAM_FORMAT_S16_LE;
dai_dev->dai_config.frame_size = 16;
dai_dev->dai_config.bclk_fs = 32; /* 50 BCLKs per frame
- */
dai_dev->dai_config.mclk_fs = 256;
break;
default:
goto error;
} dai_dev->dai_config.clk_src = SSP_CLK_EXT;
comp_dai_config(dai_dev->dev.cd, &dai_dev->dai_config); diff --git
a/src/platform/baytrail/include/platform/platform.h b/src/platform/baytrail/include/platform/platform.h index e8395a4..7af3b36 100644 --- a/src/platform/baytrail/include/platform/platform.h +++ b/src/platform/baytrail/include/platform/platform.h @@ -39,7 +39,7 @@ #define PLATFORM_SSP_PORT 2
/* default SSP stream format - need aligned with codec setting*/ -#define PLATFORM_SSP_STREAM_FORMAT STREAM_FORMAT_S16_LE +#define PLATFORM_SSP_STREAM_FORMAT STREAM_FORMAT_S24_3LE
/* IPC Interrupt */ #define PLATFORM_IPC_INTERUPT IRQ_NUM_EXT_IA @@ -62,7 +62,7 @@ #define PLAT_HOST_PERIODS 2 /* give enough latency for
DMA refill
*/
/* Platform Dev DMA buffer config - these should align with DMA engine */ -#define PLAT_DEV_PERSIZE 256 /* must be multiple of DMA+DEV burst
size */
+#define PLAT_DEV_PERSIZE 512 /* must be multiple of DMA+DEV burst
size */
#define PLAT_DEV_PERIODS 2 /* give enough latency for DMA refill
*/
/* DMA channel drain timeout in microseconds */
On Thu, 2016-12-22 at 17:27 +0800, Keyon Jie wrote:
This series is created to change the SSP format setting for both Tx and Rx, and it is verified on MinnowMax + ALC5651 codec with I2S stereo both SSP_CLK_EXT and SSP_CLK_AUDIO mode. Changes including:
- change ssp clock from 25M to 19.2M;
- add 16bit <==> 24bit volume converting functions;
- change to get dai format from host;
- change to get ssp stream format from host;
- remove the shim SSP divider and use SSCR0.SCR
for BCLK generating.
I've applied patches 1 - 4.
I dont want to introduce any IPC changes atm, please just hard code the new SSP format in intel-ipc.
Please also change volume_prepare so that :-
1) If source == host then s16_s32 2) if dest == host then S32_to_s16 3) if source == ssp then s24_to_s32 4) if dest == ssp then s32_to_s24
The data format used by all other copies (including mixer will be s32_to_s32). That we we are using 32bit internally. You will probably need to increase some buffer sizes internally.
We can then also remove any volume copies we dont use.
Liam
changes from v1:
- change to make dai format configurable;
- change to make ssp stream format configurable;
- clean shim SSP divider code;
- optimize volume copy functions.
Keyon Jie (7): ssp: switch to use SCR for BCLK generation. platform: switch default ssp clock to 19.2M volume: add 16bit<==>24bit volume copy function and mapping ssp: switch dai format form PCM B mode to normal I2S mode intel-ipc: get dai format from ipc dai: add stream_format to dai_data for codec stream intel-ipc: change to get ssp stream format from ipc
src/audio/dai.c | 10 ++ src/audio/volume.c | 119 ++++++++++++--------- src/drivers/ssp.c | 5 +- src/include/reef/dai.h | 1 + src/include/reef/stream.h | 20 ++++ src/include/uapi/intel-ipc.h | 2 + src/ipc/intel-ipc.c | 32 +++--- src/platform/baytrail/include/platform/platform.h | 10 +- src/platform/baytrail/platform.c | 120 ---------------------- 9 files changed, 126 insertions(+), 193 deletions(-)
participants (3)
-
Jie, Yang
-
Keyon Jie
-
Liam Girdwood