[Linux-stm32] [PATCH] Subject: ASoC stm32_sai: fix incorrect BCLK polarity for DSP_A/B, LEFT_J

Tomasz Merta Tomasz.Merta at arrow.com
Fri Apr 3 14:07:52 UTC 2026


From 553c09cfa84fa801fbd8dcd5c9ae96e94a54ee31 Mon Sep 17 00:00:00 2001

Tomasz Merta
Software Engineer
E: Tomasz.Merta at arrow.com
Arrow Electronics | arrow.com
From: Tomasz Merta <tomasz.merta at arrow.com>
Date: Fri, 3 Apr 2026 10:33:11 +0200
Subject: [PATCH] Subject: ASoC stm32_sai: fix incorrect BCLK polarity for
DSP_A/B, LEFT_J

The STM32 SAI driver do not set the clock strobing bit (CKSTR) for DSP_A,
DSP_B and LEFT_J formats, causing data to be sampled on the wrong BCLK
edge when SND_SOC_DAIFMT_NB_NF is used.

Per ALSA convention, NB_NF requires sampling on the rising BCLK edge.
The STM32MP25 SAI reference manual states that CKSTR=1 is required for
signals received by the SAI to be sampled on the SCK rising edge.
Without setting CKSTR=1, the SAI samples on the falling edge, violating
the NB_NF convention. For comparison, the NXP FSL SAI driver correctly
sets FSL_SAI_CR2_BCP for DSP_A, DSP_B and LEFT_J, consistent with its
I2S handling.

This patch adds SAI_XCR1_CKSTR for DSP_A, DSP_B and LEFT_J in
stm32_sai_set_dai_fmt which was verified empirically with a cs47l35 codec.
RIGHT_J (LSB) is not investigated and addressed by this patch.

Note: the STM32 I2S driver (stm32_i2s_set_dai_fmt) may have the same issue
for DSP_A mode, as I2S_CGFR_CKPOL is not set. This has not been verified
and is left for a separate investigation.

Signed-off-by: Tomasz Merta <tomasz.merta at arrow.com>
---
 sound/soc/stm/stm32_sai_sub.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c
index 450e1585edee..3e82fa90e719 100644
--- a/sound/soc/stm/stm32_sai_sub.c
+++ b/sound/soc/stm/stm32_sai_sub.c
@@ -802,6 +802,7 @@ static int stm32_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
            break;
      /* Left justified */
      case SND_SOC_DAIFMT_MSB:
+           cr1 |= SAI_XCR1_CKSTR;
            frcr |= SAI_XFRCR_FSPOL | SAI_XFRCR_FSDEF;
            break;
      /* Right justified */
@@ -809,9 +810,11 @@ static int stm32_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
            frcr |= SAI_XFRCR_FSPOL | SAI_XFRCR_FSDEF;
            break;
      case SND_SOC_DAIFMT_DSP_A:
+           cr1 |= SAI_XCR1_CKSTR;
            frcr |= SAI_XFRCR_FSPOL | SAI_XFRCR_FSOFF;
            break;
      case SND_SOC_DAIFMT_DSP_B:
+           cr1 |= SAI_XCR1_CKSTR;
            frcr |= SAI_XFRCR_FSPOL;
            break;
      default:
--
2.34.1
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://st-md-mailman.stormreply.com/pipermail/linux-stm32/attachments/20260403/5da79c4e/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image272196.png
Type: image/png
Size: 7783 bytes
Desc: image272196.png
URL: <http://st-md-mailman.stormreply.com/pipermail/linux-stm32/attachments/20260403/5da79c4e/attachment.png>


More information about the Linux-stm32 mailing list