From c100e9a9e807f2131dedf09e838774c312588023 Mon Sep 17 00:00:00 2001 From: wangjianyu3 Date: Mon, 30 Mar 2026 15:22:53 +0800 Subject: [PATCH] esp_i2s: use actual channel count for BCLK calculation The I2S BCLK frequency is calculated as: bclk = sample_rate * total_slot * data_width Previously, total_slot was always taken from the static config (esp_i2s0_config / esp_i2s1_config), which is hardcoded to 2. This is correct for mono and stereo, but wrong for TDM modes with more than 2 channels (e.g. 4-channel recording with ES7210). With 4 channels but total_slot=2, the BCLK is only half of what it should be, causing the actual sample rate to be half of the requested rate (e.g. requesting 16 kHz actually samples at 8 kHz). Replace priv->config->total_slot with MAX(priv->channels, 2) in all three BCLK calculation sites (i2s_check_mclkfrequency and i2s_set_clock for both master and slave paths). The MIN of 2 preserves the I2S protocol requirement that at least 2 slots exist even for mono, while correctly scaling for multi-channel TDM configurations. Signed-off-by: wangjianyu3 --- arch/xtensa/src/common/espressif/esp_i2s.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/xtensa/src/common/espressif/esp_i2s.c b/arch/xtensa/src/common/espressif/esp_i2s.c index e664411125d..8789ced45e9 100644 --- a/arch/xtensa/src/common/espressif/esp_i2s.c +++ b/arch/xtensa/src/common/espressif/esp_i2s.c @@ -26,6 +26,8 @@ #include +#include + #include #include #include @@ -288,8 +290,6 @@ # define I2S_RCC_ATOMIC() #endif -#define MIN(x, y) ((x) < (y) ? (x) : (y)) - /**************************************************************************** * Private Types ****************************************************************************/ @@ -2012,7 +2012,7 @@ static int32_t i2s_check_mclkfrequency(struct esp_i2s_s *priv) { uint32_t mclk_freq; uint32_t mclk_multiple = priv->mclk_multiple; - uint32_t bclk = priv->rate * priv->config->total_slot * priv->data_width; + uint32_t bclk = priv->rate * MAX(priv->channels, 2) * priv->data_width; int i; /* If the master clock is divisible by both the sample rate and the bit @@ -2146,7 +2146,7 @@ static void i2s_set_clock(struct esp_i2s_s *priv) if (priv->config->role == I2S_ROLE_MASTER) { - bclk = priv->rate * priv->config->total_slot * + bclk = priv->rate * MAX(priv->channels, 2) * priv->config->data_width; mclk = priv->mclk_freq; bclk_div = mclk / bclk; @@ -2156,7 +2156,7 @@ static void i2s_set_clock(struct esp_i2s_s *priv) /* For slave mode, mclk >= bclk * 8, so fix bclk_div to 2 first */ bclk_div = 8; - bclk = priv->rate * priv->config->total_slot * + bclk = priv->rate * MAX(priv->channels, 2) * priv->config->data_width; mclk = bclk * bclk_div; }