Skip to content

Commit a6adaed

Browse files
danieldegrassefabiobaltieri
authored andcommitted
drivers: i2s: mcux_sai: fix PCM data format and respect CLK format
This commit fixes the following issues with the PCM data format output by the MCUX SAI driver: - WS signal should be only one clock cycle in length for short PCM format - Word count should not be fixed to 2, except for classic I2S format - BCLK polarity should be on falling edge for PCM long and short format Additionally, the I2S_FMT_CLK_ constants now flip the frame and bit clock polarity from the normal value expected for the selected I2S format, as expected by the API. Fixes #63041 Signed-off-by: Daniel DeGrasse <[email protected]>
1 parent b128134 commit a6adaed

File tree

1 file changed

+30
-11
lines changed

1 file changed

+30
-11
lines changed

drivers/i2s/i2s_mcux_sai.c

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -577,11 +577,18 @@ static int i2s_mcux_config(const struct device *dev, enum i2s_dir dir,
577577
SAI_GetDSPConfig(&config, kSAI_FrameSyncLenOneBitClk,
578578
word_size_bits, kSAI_Stereo,
579579
dev_cfg->tx_channel);
580+
/* We need to set the data word count manually, since the HAL
581+
* function does not
582+
*/
583+
config.serialData.dataWordNum = num_words;
584+
config.frameSync.frameSyncEarly = true;
585+
config.bitClock.bclkPolarity = kSAI_SampleOnFallingEdge;
580586
break;
581587
case I2S_FMT_DATA_FORMAT_PCM_LONG:
582588
SAI_GetTDMConfig(&config, kSAI_FrameSyncLenPerWordWidth,
583589
word_size_bits, num_words,
584590
dev_cfg->tx_channel);
591+
config.bitClock.bclkPolarity = kSAI_SampleOnFallingEdge;
585592
break;
586593
default:
587594
LOG_ERR("Unsupported I2S data format");
@@ -629,31 +636,43 @@ static int i2s_mcux_config(const struct device *dev, enum i2s_dir dir,
629636
/* clock signal polarity */
630637
switch (i2s_cfg->format & I2S_FMT_CLK_FORMAT_MASK) {
631638
case I2S_FMT_CLK_NF_NB:
632-
config.frameSync.frameSyncPolarity =
633-
kSAI_PolarityActiveLow;
634-
config.bitClock.bclkSrcSwap = false;
639+
/* No action required, leave the configuration untouched */
635640
break;
636641

637642
case I2S_FMT_CLK_NF_IB:
638-
config.frameSync.frameSyncPolarity =
639-
kSAI_PolarityActiveLow;
640-
config.bitClock.bclkSrcSwap = true;
643+
/* Swap bclk polarity */
644+
config.bitClock.bclkPolarity =
645+
(config.bitClock.bclkPolarity == kSAI_SampleOnFallingEdge) ?
646+
kSAI_SampleOnRisingEdge :
647+
kSAI_SampleOnFallingEdge;
641648
break;
642649

643650
case I2S_FMT_CLK_IF_NB:
651+
/* Swap frame sync polarity */
644652
config.frameSync.frameSyncPolarity =
645-
kSAI_PolarityActiveHigh;
646-
config.bitClock.bclkSrcSwap = false;
653+
(config.frameSync.frameSyncPolarity == kSAI_PolarityActiveHigh) ?
654+
kSAI_PolarityActiveLow :
655+
kSAI_PolarityActiveHigh;
647656
break;
648657

649658
case I2S_FMT_CLK_IF_IB:
659+
/* Swap frame sync and bclk polarity */
650660
config.frameSync.frameSyncPolarity =
651-
kSAI_PolarityActiveHigh;
652-
config.bitClock.bclkSrcSwap = true;
661+
(config.frameSync.frameSyncPolarity == kSAI_PolarityActiveHigh) ?
662+
kSAI_PolarityActiveLow :
663+
kSAI_PolarityActiveHigh;
664+
config.bitClock.bclkPolarity =
665+
(config.bitClock.bclkPolarity == kSAI_SampleOnFallingEdge) ?
666+
kSAI_SampleOnRisingEdge :
667+
kSAI_SampleOnFallingEdge;
653668
break;
654669
}
655670

656-
config.frameSync.frameSyncWidth = (uint8_t)word_size_bits;
671+
/* PCM short format always requires that WS be one BCLK cycle */
672+
if ((i2s_cfg->format & I2S_FMT_DATA_FORMAT_MASK) !=
673+
I2S_FMT_DATA_FORMAT_PCM_SHORT) {
674+
config.frameSync.frameSyncWidth = (uint8_t)word_size_bits;
675+
}
657676

658677
if (dir == I2S_DIR_TX) {
659678
memcpy(&dev_data->tx.cfg, i2s_cfg, sizeof(struct i2s_config));

0 commit comments

Comments
 (0)